xref: /netbsd-src/sys/arch/prep/include/bus.h (revision 5aefcfdc06931dd97e76246d2fe0302f7b3fe094)
1 /*	$NetBSD: bus.h,v 1.4 2000/11/27 08:53:54 matt Exp $	*/
2 /*	$OpenBSD: bus.h,v 1.1 1997/10/13 10:53:42 pefo Exp $	*/
3 
4 /*-
5  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
6  * All rights reserved.
7  *
8  * This code is derived from software contributed to The NetBSD Foundation
9  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10  * NASA Ames Research Center.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *	This product includes software developed by the NetBSD
23  *	Foundation, Inc. and its contributors.
24  * 4. Neither the name of The NetBSD Foundation nor the names of its
25  *    contributors may be used to endorse or promote products derived
26  *    from this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 /*
42  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
43  * Copyright (c) 1996 Jason R. Thorpe.  All rights reserved.
44  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
45  *
46  * Redistribution and use in source and binary forms, with or without
47  * modification, are permitted provided that the following conditions
48  * are met:
49  * 1. Redistributions of source code must retain the above copyright
50  *    notice, this list of conditions and the following disclaimer.
51  * 2. Redistributions in binary form must reproduce the above copyright
52  *    notice, this list of conditions and the following disclaimer in the
53  *    documentation and/or other materials provided with the distribution.
54  * 3. All advertising materials mentioning features or use of this software
55  *    must display the following acknowledgement:
56  *      This product includes software developed by Christopher G. Demetriou
57  *	for the NetBSD Project.
58  * 4. The name of the author may not be used to endorse or promote products
59  *    derived from this software without specific prior written permission
60  *
61  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
62  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
63  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
64  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
65  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
66  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
67  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
68  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
70  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71  */
72 
73 /*
74  * Copyright (c) 1997 Per Fogelstrom.  All rights reserved.
75  * Copyright (c) 1996 Niklas Hallqvist.  All rights reserved.
76  *
77  * Redistribution and use in source and binary forms, with or without
78  * modification, are permitted provided that the following conditions
79  * are met:
80  * 1. Redistributions of source code must retain the above copyright
81  *    notice, this list of conditions and the following disclaimer.
82  * 2. Redistributions in binary form must reproduce the above copyright
83  *    notice, this list of conditions and the following disclaimer in the
84  *    documentation and/or other materials provided with the distribution.
85  * 3. All advertising materials mentioning features or use of this software
86  *    must display the following acknowledgement:
87  *      This product includes software developed by Christopher G. Demetriou
88  *	for the NetBSD Project.
89  * 4. The name of the author may not be used to endorse or promote products
90  *    derived from this software without specific prior written permission
91  *
92  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
93  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
94  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
95  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
96  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
99  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
101  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102  */
103 
104 #ifndef _PREP_BUS_H_
105 #define _PREP_BUS_H_
106 
107 #include <machine/pio.h>
108 
109 /*
110  * Values for the Be bus space tag, not to be used directly by MI code.
111  */
112 #define	PREP_BUS_SPACE_IO	0x80000000	/* i/o space */
113 #define PREP_BUS_SPACE_MEM	0xC0000000	/* mem space */
114 
115 /*
116  * Address conversion as seen from a PCI master.
117  */
118 #define MPC105_DIRECT_MAPPED_SPACE	0x80000000
119 #define PHYS_TO_PCI_MEM(x)	((x) | MPC105_DIRECT_MAPPED_SPACE)
120 #define PCI_MEM_TO_PHYS(x)	((x) & ~MPC105_DIRECT_MAPPED_SPACE)
121 
122 /*
123  * Bus access types.
124  */
125 typedef u_int32_t bus_addr_t;
126 typedef u_int32_t bus_size_t;
127 typedef	u_int32_t bus_space_handle_t;
128 typedef	const struct prep_bus_space {
129 	u_int32_t pbs_type;
130 	bus_addr_t pbs_base;
131 	bus_addr_t pbs_limit;
132 } *bus_space_tag_t;
133 
134 extern const struct prep_bus_space prep_io_space_tag;
135 extern const struct prep_bus_space prep_isa_io_space_tag;
136 extern const struct prep_bus_space prep_mem_space_tag;
137 extern const struct prep_bus_space prep_isa_mem_space_tag;
138 
139 #define BUS_SPACE_MAP_CACHEABLE         0x01
140 #define BUS_SPACE_MAP_LINEAR            0x02
141 #define	BUS_SPACE_MAP_PREFETCHABLE	0x04
142 
143 #ifdef __STDC__
144 #define CAT(a,b)	a##b
145 #define CAT3(a,b,c)	a##b##c
146 #else
147 #define CAT(a,b)	a/**/b
148 #define CAT3(a,b,c)	a/**/b/**/c
149 #endif
150 
151 /*
152  * Access methods for bus resources
153  */
154 
155 #define	__BUS_SPACE_HAS_STREAM_METHODS
156 
157 /*
158  *	int bus_space_map  __P((bus_space_tag_t t, bus_addr_t addr,
159  *	    bus_size_t size, int flags, bus_space_handle_t *bshp));
160  *
161  * Map a region of bus space.
162  */
163 
164 int	prep_memio_map __P((bus_space_tag_t t, bus_addr_t addr,
165 	    bus_size_t size, int flags, bus_space_handle_t *bshp));
166 
167 #define bus_space_map(t, a, s, f, hp)					\
168     prep_memio_map((t), (a), (s), (f), (hp))
169 
170 /*
171  *	int bus_space_unmap __P((bus_space_tag_t t,
172  *	    bus_space_handle_t bsh, bus_size_t size));
173  *
174  * Unmap a region of bus space.
175  */
176 
177 void	prep_memio_unmap __P((bus_space_tag_t t, bus_space_handle_t bsh,
178 	    bus_size_t size));
179 
180 #define bus_space_unmap(t, h, s)					\
181     prep_memio_unmap((t), (h), (s))
182 
183 /*
184  *	int bus_space_subregion __P((bus_space_tag_t t,
185  *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
186  *	    bus_space_handle_t *nbshp));
187  *
188  * Get a new handle for a subregion of an already-mapped area of bus space.
189  */
190 
191 #define bus_space_subregion(t, h, o, s, hp)				\
192     ((*(hp) = (h) + (o)), 0)
193 
194 /*
195  *	int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
196  *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
197  *	    bus_size_t boundary, int flags, bus_addr_t *bpap,
198  *	    bus_space_handle_t *bshp));
199  *
200  * Allocate a region of bus space.
201  */
202 
203 int	prep_memio_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
204 	    bus_addr_t rend, bus_size_t size, bus_size_t align,
205 	    bus_size_t boundary, int flags, bus_addr_t *bpap,
206 	    bus_space_handle_t *bshp));
207 
208 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)			\
209     prep_memio_alloc((t), (rs), (re), (s), (a), (b), (f), (ap), (hp))
210 
211 /*
212  *	int bus_space_free __P((bus_space_tag_t t,
213  *	    bus_space_handle_t bsh, bus_size_t size));
214  *
215  * Free a region of bus space.
216  */
217 
218 void	prep_memio_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
219 	    bus_size_t size));
220 
221 #define	bus_space_free(t, h, s)						\
222     prep_memio_free((t), (h), (s))
223 
224 /*
225  *	u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
226  *	    bus_space_handle_t bsh, bus_size_t offset));
227  *
228  * Read a 1, 2, 4, or 8 byte quantity from bus space
229  * described by tag/handle/offset.
230  */
231 
232 #define bus_space_read(n,m)						      \
233 static __inline CAT3(u_int,m,_t)					      \
234 CAT(bus_space_read_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,	      \
235      bus_size_t offset)							      \
236 {									      \
237 	return CAT3(in,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)));  \
238 }
239 
240 bus_space_read(1,8)
241 bus_space_read(2,16)
242 bus_space_read(4,32)
243 #define	bus_space_read_8	!!! bus_space_read_8 unimplemented !!!
244 
245 /*
246  *	u_intN_t bus_space_read_stream_N __P((bus_space_tag_t tag,
247  *	    bus_space_handle_t bsh, bus_size_t offset));
248  *
249  * Read a 2, 4, or 8 byte stream quantity from bus space
250  * described by tag/handle/offset.
251  */
252 
253 #define bus_space_read_stream(n,m)					      \
254 static __inline CAT3(u_int,m,_t)					      \
255 CAT(bus_space_read_stream_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,    \
256      bus_size_t offset)							      \
257 {									      \
258 	return CAT(in,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)));  \
259 }
260 
261 bus_space_read_stream(2,16)
262 bus_space_read_stream(4,32)
263 #define	bus_space_read_stream_8	!!! bus_space_read_stream_8 unimplemented !!!
264 
265 /*
266  *	void bus_space_read_multi_N __P((bus_space_tag_t tag,
267  *	    bus_space_handle_t bsh, bus_size_t offset,
268  *	    u_intN_t *addr, size_t count));
269  *
270  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
271  * described by tag/handle/offset and copy into buffer provided.
272  */
273 
274 #define bus_space_read_multi(n,m)					      \
275 static __inline void							      \
276 CAT(bus_space_read_multi_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,     \
277      bus_size_t offset, CAT3(u_int,m,_t) *addr, size_t count)		      \
278 {									      \
279 	CAT3(ins,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)),	      \
280 	    (CAT3(u_int,m,_t) *)addr, (size_t)count);			      \
281 }
282 
283 bus_space_read_multi(1,8)
284 bus_space_read_multi(2,16)
285 bus_space_read_multi(4,32)
286 #define	bus_space_read_multi_8	!!! bus_space_read_multi_8 not implemented !!!
287 
288 /*
289  *	void bus_space_read_multi_stream_N __P((bus_space_tag_t tag,
290  *	    bus_space_handle_t bsh, bus_size_t offset,
291  *	    u_intN_t *addr, size_t count));
292  *
293  * Read `count' 2, 4, or 8 byte stream quantities from bus space
294  * described by tag/handle/offset and copy into buffer provided.
295  */
296 
297 #define bus_space_read_multi_stream(n,m)				      \
298 static __inline void							      \
299 CAT(bus_space_read_multi_stream_,n)(bus_space_tag_t tag,		      \
300      bus_space_handle_t bsh,						      \
301      bus_size_t offset, CAT3(u_int,m,_t) *addr, size_t count)		      \
302 {									      \
303 	CAT(ins,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)),	      \
304 	    (CAT3(u_int,m,_t) *)addr, (size_t)count);			      \
305 }
306 
307 bus_space_read_multi_stream(2,16)
308 bus_space_read_multi_stream(4,32)
309 #define	bus_space_read_multi_stream_8					      \
310 	!!! bus_space_read_multi_stream_8 not implemented !!!
311 
312 /*
313  *	void bus_space_write_N __P((bus_space_tag_t tag,
314  *	    bus_space_handle_t bsh, bus_size_t offset,
315  *	    u_intN_t value));
316  *
317  * Write the 1, 2, 4, or 8 byte value `value' to bus space
318  * described by tag/handle/offset.
319  */
320 
321 #define bus_space_write(n,m)						      \
322 static __inline void							      \
323 CAT(bus_space_write_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,	      \
324      bus_size_t offset, CAT3(u_int,m,_t) x)				      \
325 {									      \
326 	CAT3(out,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), x);     \
327 }
328 
329 bus_space_write(1,8)
330 bus_space_write(2,16)
331 bus_space_write(4,32)
332 #define	bus_space_write_8	!!! bus_space_write_8 unimplemented !!!
333 
334 /*
335  *	void bus_space_write_stream_N __P((bus_space_tag_t tag,
336  *	    bus_space_handle_t bsh, bus_size_t offset,
337  *	    u_intN_t value));
338  *
339  * Write the 2, 4, or 8 byte stream value `value' to bus space
340  * described by tag/handle/offset.
341  */
342 
343 #define bus_space_write_stream(n,m)					      \
344 static __inline void							      \
345 CAT(bus_space_write_stream_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,   \
346      bus_size_t offset, CAT3(u_int,m,_t) x)				      \
347 {									      \
348 	CAT(out,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), x);     \
349 }
350 
351 bus_space_write_stream(2,16)
352 bus_space_write_stream(4,32)
353 #define	bus_space_write_stream_8 !!! bus_space_write_stream_8 unimplemented !!!
354 
355 /*
356  *	void bus_space_write_multi_N __P((bus_space_tag_t tag,
357  *	    bus_space_handle_t bsh, bus_size_t offset,
358  *	    const u_intN_t *addr, size_t count));
359  *
360  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
361  * provided to bus space described by tag/handle/offset.
362  */
363 
364 #define bus_space_write_multi(n,m)					      \
365 static __inline void							      \
366 CAT(bus_space_write_multi_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,    \
367      bus_size_t offset, const CAT3(u_int,m,_t) *addr, size_t count)	      \
368 {									      \
369 	CAT3(outs,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)),	      \
370 	    (CAT3(u_int,m,_t) *)addr, (size_t)count);			      \
371 }
372 
373 bus_space_write_multi(1,8)
374 bus_space_write_multi(2,16)
375 bus_space_write_multi(4,32)
376 #define	bus_space_write_multi_8	!!! bus_space_write_multi_8 not implemented !!!
377 
378 /*
379  *	void bus_space_write_multi_stream_N __P((bus_space_tag_t tag,
380  *	    bus_space_handle_t bsh, bus_size_t offset,
381  *	    const u_intN_t *addr, size_t count));
382  *
383  * Write `count' 2, 4, or 8 byte stream quantities from the buffer
384  * provided to bus space described by tag/handle/offset.
385  */
386 
387 #define bus_space_write_multi_stream(n,m)				      \
388 static __inline void							      \
389 CAT(bus_space_write_multi_stream_,n)(bus_space_tag_t tag,		      \
390      bus_space_handle_t bsh,						      \
391      bus_size_t offset, const CAT3(u_int,m,_t) *addr, size_t count)	      \
392 {									      \
393 	CAT(outs,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)),	      \
394 	    (CAT3(u_int,m,_t) *)addr, (size_t)count);			      \
395 }
396 
397 bus_space_write_multi_stream(2,16)
398 bus_space_write_multi_stream(4,32)
399 #define	bus_space_write_multi_stream_8					      \
400 	!!! bus_space_write_multi_stream_8 not implemented !!!
401 
402 /*
403  *	void bus_space_read_region_N __P((bus_space_tag_t tag,
404  *	    bus_space_handle_t bsh, bus_size_t offset,
405  *	    u_intN_t *addr, size_t count));
406  *
407  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
408  * described by tag/handle and starting at `offset' and copy into
409  * buffer provided.
410  */
411 static __inline void bus_space_read_region_1 __P((bus_space_tag_t,
412 	bus_space_handle_t, bus_size_t, u_int8_t *, size_t));
413 static __inline void bus_space_read_region_2 __P((bus_space_tag_t,
414 	bus_space_handle_t, bus_size_t, u_int16_t *, size_t));
415 static __inline void bus_space_read_region_4 __P((bus_space_tag_t,
416 	bus_space_handle_t, bus_size_t, u_int32_t *, size_t));
417 
418 static __inline void
419 bus_space_read_region_1(tag, bsh, offset, addr, count)
420 	bus_space_tag_t tag;
421 	bus_space_handle_t bsh;
422 	bus_size_t offset;
423 	u_int8_t *addr;
424 	size_t count;
425 {
426 	volatile u_int8_t *s;
427 
428 	s = (volatile u_int8_t *)(bsh + offset);
429 	while (count--)
430 		*addr++ = *s++;
431 	__asm__ volatile("eieio; sync");
432 }
433 
434 static __inline void
435 bus_space_read_region_2(tag, bsh, offset, addr, count)
436 	bus_space_tag_t tag;
437 	bus_space_handle_t bsh;
438 	bus_size_t offset;
439 	u_int16_t *addr;
440 	size_t count;
441 {
442 	volatile u_int16_t *s;
443 
444 	s = (volatile u_int16_t *)(bsh + offset);
445 	while (count--)
446 		__asm__ volatile("lhbrx %0, 0, %1" :
447 			"=r"(*addr++) : "r"(s++));
448 	__asm__ volatile("eieio; sync");
449 }
450 
451 static __inline void
452 bus_space_read_region_4(tag, bsh, offset, addr, count)
453 	bus_space_tag_t tag;
454 	bus_space_handle_t bsh;
455 	bus_size_t offset;
456 	u_int32_t *addr;
457 	size_t count;
458 {
459 	volatile u_int32_t *s;
460 
461 	s = (volatile u_int32_t *)(bsh + offset);
462 	while (count--)
463 		__asm__ volatile("lwbrx %0, 0, %1" :
464 			"=r"(*addr++) : "r"(s++));
465 	__asm__ volatile("eieio; sync");
466 }
467 
468 #define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
469 
470 /*
471  *	void bus_space_read_region_stream_N __P((bus_space_tag_t tag,
472  *	    bus_space_handle_t bsh, bus_size_t offset,
473  *	    u_intN_t *addr, size_t count));
474  *
475  * Read `count' 2, 4, or 8 byte stream quantities from bus space
476  * described by tag/handle and starting at `offset' and copy into
477  * buffer provided.
478  */
479 static __inline void bus_space_read_region_stream_2 __P((bus_space_tag_t,
480 	bus_space_handle_t, bus_size_t, u_int16_t *, size_t));
481 static __inline void bus_space_read_region_stream_4 __P((bus_space_tag_t,
482 	bus_space_handle_t, bus_size_t, u_int32_t *, size_t));
483 
484 static __inline void
485 bus_space_read_region_stream_2(tag, bsh, offset, addr, count)
486 	bus_space_tag_t tag;
487 	bus_space_handle_t bsh;
488 	bus_size_t offset;
489 	u_int16_t *addr;
490 	size_t count;
491 {
492 	volatile u_int16_t *s;
493 
494 	s = (volatile u_int16_t *)(bsh + offset);
495 	while (count--)
496 		*addr++ = *s++;
497 	__asm__ volatile("eieio; sync");
498 }
499 
500 static __inline void
501 bus_space_read_region_stream_4(tag, bsh, offset, addr, count)
502 	bus_space_tag_t tag;
503 	bus_space_handle_t bsh;
504 	bus_size_t offset;
505 	u_int32_t *addr;
506 	size_t count;
507 {
508 	volatile u_int32_t *s;
509 
510 	s = (volatile u_int32_t *)(bsh + offset);
511 	while (count--)
512 		*addr++ = *s++;
513 	__asm__ volatile("eieio; sync");
514 }
515 
516 #define	bus_space_read_region_stream_8					      \
517 	!!! bus_space_read_region_stream_8 unimplemented !!!
518 
519 /*
520  *	void bus_space_write_region_N __P((bus_space_tag_t tag,
521  *	    bus_space_handle_t bsh, bus_size_t offset,
522  *	    const u_intN_t *addr, size_t count));
523  *
524  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
525  * to bus space described by tag/handle starting at `offset'.
526  */
527 static __inline void bus_space_write_region_1 __P((bus_space_tag_t,
528 	bus_space_handle_t, bus_size_t, const u_int8_t *, size_t));
529 static __inline void bus_space_write_region_2 __P((bus_space_tag_t,
530 	bus_space_handle_t, bus_size_t, const u_int16_t *, size_t));
531 static __inline void bus_space_write_region_4 __P((bus_space_tag_t,
532 	bus_space_handle_t, bus_size_t, const u_int32_t *, size_t));
533 
534 static __inline void
535 bus_space_write_region_1(tag, bsh, offset, addr, count)
536 	bus_space_tag_t tag;
537 	bus_space_handle_t bsh;
538 	bus_size_t offset;
539 	const u_int8_t *addr;
540 	size_t count;
541 {
542 	volatile u_int8_t *d;
543 
544 	d = (volatile u_int8_t *)(bsh + offset);
545 	while (count--)
546 		*d++ = *addr++;
547 	__asm__ volatile("eieio; sync");
548 }
549 
550 static __inline void
551 bus_space_write_region_2(tag, bsh, offset, addr, count)
552 	bus_space_tag_t tag;
553 	bus_space_handle_t bsh;
554 	bus_size_t offset;
555 	const u_int16_t *addr;
556 	size_t count;
557 {
558 	volatile u_int16_t *d;
559 
560 	d = (volatile u_int16_t *)(bsh + offset);
561 	while (count--)
562 		__asm__ volatile("sthbrx %0, 0, %1" ::
563 			"r"(*addr++), "r"(d++));
564 	__asm__ volatile("eieio; sync");
565 }
566 
567 static __inline void
568 bus_space_write_region_4(tag, bsh, offset, addr, count)
569 	bus_space_tag_t tag;
570 	bus_space_handle_t bsh;
571 	bus_size_t offset;
572 	const u_int32_t *addr;
573 	size_t count;
574 {
575 	volatile u_int32_t *d;
576 
577 	d = (volatile u_int32_t *)(bsh + offset);
578 	while (count--)
579 		__asm__ volatile("stwbrx %0, 0, %1" ::
580 			"r"(*addr++), "r"(d++));
581 	__asm__ volatile("eieio; sync");
582 }
583 
584 #define	bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!!
585 
586 /*
587  *	void bus_space_write_region_stream_N __P((bus_space_tag_t tag,
588  *	    bus_space_handle_t bsh, bus_size_t offset,
589  *	    const u_intN_t *addr, size_t count));
590  *
591  * Write `count' 2, 4, or 8 byte stream quantities from the buffer provided
592  * to bus space described by tag/handle starting at `offset'.
593  */
594 static __inline void bus_space_write_region_stream_2 __P((bus_space_tag_t,
595 	bus_space_handle_t, bus_size_t, const u_int16_t *, size_t));
596 static __inline void bus_space_write_region_stream_4 __P((bus_space_tag_t,
597 	bus_space_handle_t, bus_size_t, const u_int32_t *, size_t));
598 
599 static __inline void
600 bus_space_write_region_stream_2(tag, bsh, offset, addr, count)
601 	bus_space_tag_t tag;
602 	bus_space_handle_t bsh;
603 	bus_size_t offset;
604 	const u_int16_t *addr;
605 	size_t count;
606 {
607 	volatile u_int16_t *d;
608 
609 	d = (volatile u_int16_t *)(bsh + offset);
610 	while (count--)
611 		*d++ = *addr++;
612 	__asm__ volatile("eieio; sync");
613 }
614 
615 static __inline void
616 bus_space_write_region_stream_4(tag, bsh, offset, addr, count)
617 	bus_space_tag_t tag;
618 	bus_space_handle_t bsh;
619 	bus_size_t offset;
620 	const u_int32_t *addr;
621 	size_t count;
622 {
623 	volatile u_int32_t *d;
624 
625 	d = (volatile u_int32_t *)(bsh + offset);
626 	while (count--)
627 		*d++ = *addr++;
628 	__asm__ volatile("eieio; sync");
629 }
630 
631 #define	bus_space_write_region_stream_8					      \
632 	 !!! bus_space_write_region_stream_8 unimplemented !!!
633 
634 /*
635  *	void bus_space_set_multi_N __P((bus_space_tag_t tag,
636  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
637  *	    size_t count));
638  *
639  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
640  * by tag/handle/offset `count' times.
641  */
642 static __inline void bus_space_set_multi_1 __P((bus_space_tag_t,
643 	bus_space_handle_t, bus_size_t, u_int8_t, size_t));
644 static __inline void bus_space_set_multi_2 __P((bus_space_tag_t,
645 	bus_space_handle_t, bus_size_t, u_int16_t, size_t));
646 static __inline void bus_space_set_multi_4 __P((bus_space_tag_t,
647 	bus_space_handle_t, bus_size_t, u_int32_t, size_t));
648 
649 static __inline void
650 bus_space_set_multi_1(tag, bsh, offset, val, count)
651 	bus_space_tag_t tag;
652 	bus_space_handle_t bsh;
653 	bus_size_t offset;
654 	u_int8_t val;
655 	size_t count;
656 {
657 	volatile u_int8_t *d;
658 
659 	d = (volatile u_int8_t *)(bsh + offset);
660 	while (count--)
661 		*d = val;
662 	__asm__ volatile("eieio; sync");
663 }
664 
665 static __inline void
666 bus_space_set_multi_2(tag, bsh, offset, val, count)
667 	bus_space_tag_t tag;
668 	bus_space_handle_t bsh;
669 	bus_size_t offset;
670 	u_int16_t val;
671 	size_t count;
672 {
673 	volatile u_int16_t *d;
674 
675 	d = (volatile u_int16_t *)(bsh + offset);
676 	while (count--)
677 		__asm__ volatile("sthbrx %0, 0, %1" ::
678 			"r"(val), "r"(d));
679 	__asm__ volatile("eieio; sync");
680 }
681 
682 static __inline void
683 bus_space_set_multi_4(tag, bsh, offset, val, count)
684 	bus_space_tag_t tag;
685 	bus_space_handle_t bsh;
686 	bus_size_t offset;
687 	u_int32_t val;
688 	size_t count;
689 {
690 	volatile u_int32_t *d;
691 
692 	d = (volatile u_int32_t *)(bsh + offset);
693 	while (count--)
694 		__asm__ volatile("stwbrx %0, 0, %1" ::
695 			"r"(val), "r"(d));
696 	__asm__ volatile("eieio; sync");
697 }
698 
699 #define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
700 
701 /*
702  *	void bus_space_set_multi_stream_N __P((bus_space_tag_t tag,
703  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
704  *	    size_t count));
705  *
706  * Write the 2, 4, or 8 byte stream value `val' to bus space described
707  * by tag/handle/offset `count' times.
708  */
709 static __inline void bus_space_set_multi_stream_2 __P((bus_space_tag_t,
710 	bus_space_handle_t, bus_size_t, u_int16_t, size_t));
711 static __inline void bus_space_set_multi_stream_4 __P((bus_space_tag_t,
712 	bus_space_handle_t, bus_size_t, u_int32_t, size_t));
713 
714 static __inline void
715 bus_space_set_multi_stream_2(tag, bsh, offset, val, count)
716 	bus_space_tag_t tag;
717 	bus_space_handle_t bsh;
718 	bus_size_t offset;
719 	u_int16_t val;
720 	size_t count;
721 {
722 	volatile u_int16_t *d;
723 
724 	d = (volatile u_int16_t *)(bsh + offset);
725 	while (count--)
726 		*d = val;
727 	__asm__ volatile("eieio; sync");
728 }
729 
730 static __inline void
731 bus_space_set_multi_stream_4(tag, bsh, offset, val, count)
732 	bus_space_tag_t tag;
733 	bus_space_handle_t bsh;
734 	bus_size_t offset;
735 	u_int32_t val;
736 	size_t count;
737 {
738 	volatile u_int32_t *d;
739 
740 	d = (volatile u_int32_t *)(bsh + offset);
741 	while (count--)
742 		*d = val;
743 	__asm__ volatile("eieio; sync");
744 }
745 
746 #define	bus_space_set_multi_stream_8					      \
747 	!!! bus_space_set_multi_stream_8 unimplemented !!!
748 
749 /*
750  *	void bus_space_set_region_N __P((bus_space_tag_t tag,
751  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
752  *	    size_t count));
753  *
754  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
755  * by tag/handle starting at `offset'.
756  */
757 static __inline void bus_space_set_region_1 __P((bus_space_tag_t,
758 	bus_space_handle_t, bus_size_t, u_int8_t, size_t));
759 static __inline void bus_space_set_region_2 __P((bus_space_tag_t,
760 	bus_space_handle_t, bus_size_t, u_int16_t, size_t));
761 static __inline void bus_space_set_region_4 __P((bus_space_tag_t,
762 	bus_space_handle_t, bus_size_t, u_int32_t, size_t));
763 
764 static __inline void
765 bus_space_set_region_1(tag, bsh, offset, val, count)
766 	bus_space_tag_t tag;
767 	bus_space_handle_t bsh;
768 	bus_size_t offset;
769 	u_int8_t val;
770 	size_t count;
771 {
772 	volatile u_int8_t *d;
773 
774 	d = (volatile u_int8_t *)(bsh + offset);
775 	while (count--)
776 		*d++ = val;
777 	__asm__ volatile("eieio; sync");
778 }
779 
780 static __inline void
781 bus_space_set_region_2(tag, bsh, offset, val, count)
782 	bus_space_tag_t tag;
783 	bus_space_handle_t bsh;
784 	bus_size_t offset;
785 	u_int16_t val;
786 	size_t count;
787 {
788 	volatile u_int16_t *d;
789 
790 	d = (volatile u_int16_t *)(bsh + offset);
791 	while (count--)
792 		__asm__ volatile("sthbrx %0, 0, %1" ::
793 			"r"(val), "r"(d++));
794 	__asm__ volatile("eieio; sync");
795 }
796 
797 static __inline void
798 bus_space_set_region_4(tag, bsh, offset, val, count)
799 	bus_space_tag_t tag;
800 	bus_space_handle_t bsh;
801 	bus_size_t offset;
802 	u_int32_t val;
803 	size_t count;
804 {
805 	volatile u_int32_t *d;
806 
807 	d = (volatile u_int32_t *)(bsh + offset);
808 	while (count--)
809 		__asm__ volatile("stwbrx %0, 0, %1" ::
810 			"r"(val), "r"(d++));
811 	__asm__ volatile("eieio; sync");
812 }
813 
814 #define	bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
815 
816 /*
817  *	void bus_space_set_region_stream_N __P((bus_space_tag_t tag,
818  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
819  *	    size_t count));
820  *
821  * Write `count' 2, 4, or 8 byte stream value `val' to bus space described
822  * by tag/handle starting at `offset'.
823  */
824 static __inline void bus_space_set_region_stream_2 __P((bus_space_tag_t,
825 	bus_space_handle_t, bus_size_t, u_int16_t, size_t));
826 static __inline void bus_space_set_region_stream_4 __P((bus_space_tag_t,
827 	bus_space_handle_t, bus_size_t, u_int32_t, size_t));
828 
829 
830 static __inline void
831 bus_space_set_region_stream_2(tag, bsh, offset, val, count)
832 	bus_space_tag_t tag;
833 	bus_space_handle_t bsh;
834 	bus_size_t offset;
835 	u_int16_t val;
836 	size_t count;
837 {
838 	volatile u_int16_t *d;
839 
840 	d = (volatile u_int16_t *)(bsh + offset);
841 	while (count--)
842 		*d++ = val;
843 	__asm__ volatile("eieio; sync");
844 }
845 
846 static __inline void
847 bus_space_set_region_stream_4(tag, bsh, offset, val, count)
848 	bus_space_tag_t tag;
849 	bus_space_handle_t bsh;
850 	bus_size_t offset;
851 	u_int32_t val;
852 	size_t count;
853 {
854 	volatile u_int32_t *d;
855 
856 	d = (volatile u_int32_t *)(bsh + offset);
857 	while (count--)
858 		*d++ = val;
859 	__asm__ volatile("eieio; sync");
860 }
861 
862 #define	bus_space_set_region_stream_8					      \
863 	!!! bus_space_set_region_stream_8 unimplemented !!!
864 
865 /*
866  *	void bus_space_copy_region_N __P((bus_space_tag_t tag,
867  *	    bus_space_handle_t bsh1, bus_size_t off1,
868  *	    bus_space_handle_t bsh2, bus_size_t off2,
869  *	    size_t count));
870  *
871  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
872  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
873  */
874 
875 static __inline void bus_space_copy_region_1 __P((bus_space_tag_t,
876 	bus_space_handle_t, bus_size_t, bus_space_handle_t,
877 	bus_size_t, size_t));
878 static __inline void bus_space_copy_region_2 __P((bus_space_tag_t,
879 	bus_space_handle_t, bus_size_t, bus_space_handle_t,
880 	bus_size_t, size_t));
881 static __inline void bus_space_copy_region_4 __P((bus_space_tag_t,
882 	bus_space_handle_t, bus_size_t, bus_space_handle_t,
883 	bus_size_t, size_t));
884 
885 static __inline void
886 bus_space_copy_region_1(t, h1, o1, h2, o2, c)
887 	bus_space_tag_t t;
888 	bus_space_handle_t h1;
889 	bus_size_t o1;
890 	bus_space_handle_t h2;
891 	bus_size_t o2;
892 	size_t c;
893 {
894 	bus_addr_t addr1 = h1 + o1;
895 	bus_addr_t addr2 = h2 + o2;
896 
897 	if (addr1 >= addr2) {
898 		/* src after dest: copy forward */
899 		for (; c != 0; c--, addr1++, addr2++)
900 			*(volatile u_int8_t *)(addr2) =
901 			    *(volatile u_int8_t *)(addr1);
902 	} else {
903 		/* dest after src: copy backwards */
904 		for (addr1 += (c - 1), addr2 += (c - 1);
905 		    c != 0; c--, addr1--, addr2--)
906 			*(volatile u_int8_t *)(addr2) =
907 			    *(volatile u_int8_t *)(addr1);
908 	}
909 }
910 
911 static __inline void
912 bus_space_copy_region_2(t, h1, o1, h2, o2, c)
913 	bus_space_tag_t t;
914 	bus_space_handle_t h1;
915 	bus_size_t o1;
916 	bus_space_handle_t h2;
917 	bus_size_t o2;
918 	size_t c;
919 {
920 	bus_addr_t addr1 = h1 + o1;
921 	bus_addr_t addr2 = h2 + o2;
922 
923 	if (addr1 >= addr2) {
924 		/* src after dest: copy forward */
925 		for (; c != 0; c--, addr1 += 2, addr2 += 2)
926 			*(volatile u_int16_t *)(addr2) =
927 			    *(volatile u_int16_t *)(addr1);
928 	} else {
929 		/* dest after src: copy backwards */
930 		for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
931 		    c != 0; c--, addr1 -= 2, addr2 -= 2)
932 			*(volatile u_int16_t *)(addr2) =
933 			    *(volatile u_int16_t *)(addr1);
934 	}
935 }
936 
937 static __inline void
938 bus_space_copy_region_4(t, h1, o1, h2, o2, c)
939 	bus_space_tag_t t;
940 	bus_space_handle_t h1;
941 	bus_size_t o1;
942 	bus_space_handle_t h2;
943 	bus_size_t o2;
944 	size_t c;
945 {
946 	bus_addr_t addr1 = h1 + o1;
947 	bus_addr_t addr2 = h2 + o2;
948 
949 	if (addr1 >= addr2) {
950 		/* src after dest: copy forward */
951 		for (; c != 0; c--, addr1 += 4, addr2 += 4)
952 			*(volatile u_int32_t *)(addr2) =
953 			    *(volatile u_int32_t *)(addr1);
954 	} else {
955 		/* dest after src: copy backwards */
956 		for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
957 		    c != 0; c--, addr1 -= 4, addr2 -= 4)
958 			*(volatile u_int32_t *)(addr2) =
959 			    *(volatile u_int32_t *)(addr1);
960 	}
961 }
962 
963 #define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
964 
965 /*
966  * Bus read/write barrier methods.
967  *
968  *	void bus_space_barrier __P((bus_space_tag_t tag,
969  *	    bus_space_handle_t bsh, bus_size_t offset,
970  *	    bus_size_t len, int flags));
971  *
972  */
973 #define	bus_space_barrier(t, h, o, l, f)	\
974 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
975 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
976 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
977 
978 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
979 
980 /*
981  * Bus DMA methods.
982  */
983 
984 /*
985  * Flags used in various bus DMA methods.
986  */
987 #define	BUS_DMA_WAITOK		0x00	/* safe to sleep (pseudo-flag) */
988 #define	BUS_DMA_NOWAIT		0x01	/* not safe to sleep */
989 #define	BUS_DMA_ALLOCNOW	0x02	/* perform resource allocation now */
990 #define	BUS_DMA_COHERENT	0x04	/* hint: map memory DMA coherent */
991 #define	BUS_DMA_BUS1		0x10	/* placeholders for bus functions... */
992 #define	BUS_DMA_BUS2		0x20
993 #define	BUS_DMA_BUS3		0x40
994 #define	BUS_DMA_BUS4		0x80
995 
996 /* Forwards needed by prototypes below. */
997 struct mbuf;
998 struct uio;
999 
1000 /*
1001  * Operations performed by bus_dmamap_sync().
1002  */
1003 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
1004 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
1005 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
1006 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
1007 
1008 typedef struct prep_bus_dma_tag		*bus_dma_tag_t;
1009 typedef struct prep_bus_dmamap		*bus_dmamap_t;
1010 
1011 /*
1012  *	bus_dma_segment_t
1013  *
1014  *	Describes a single contiguous DMA transaction.  Values
1015  *	are suitable for programming into DMA registers.
1016  */
1017 struct prep_bus_dma_segment {
1018 	bus_addr_t	ds_addr;	/* DMA address */
1019 	bus_size_t	ds_len;		/* length of transfer */
1020 };
1021 typedef struct prep_bus_dma_segment	bus_dma_segment_t;
1022 
1023 /*
1024  *	bus_dma_tag_t
1025  *
1026  *	A machine-dependent opaque type describing the implementation of
1027  *	DMA for a given bus.
1028  */
1029 
1030 struct prep_bus_dma_tag {
1031 	/*
1032 	 * The `bounce threshold' is checked while we are loading
1033 	 * the DMA map.  If the physical address of the segment
1034 	 * exceeds the threshold, an error will be returned.  The
1035 	 * caller can then take whatever action is necessary to
1036 	 * bounce the transfer.  If this value is 0, it will be
1037 	 * ignored.
1038 	 */
1039 	bus_addr_t _bounce_thresh;
1040 
1041 	/*
1042 	 * DMA mapping methods.
1043 	 */
1044 	int	(*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
1045 		    bus_size_t, bus_size_t, int, bus_dmamap_t *));
1046 	void	(*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
1047 	int	(*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
1048 		    bus_size_t, struct proc *, int));
1049 	int	(*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
1050 		    struct mbuf *, int));
1051 	int	(*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
1052 		    struct uio *, int));
1053 	int	(*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
1054 		    bus_dma_segment_t *, int, bus_size_t, int));
1055 	void	(*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
1056 	void	(*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
1057 		    bus_addr_t, bus_size_t, int));
1058 
1059 	/*
1060 	 * DMA memory utility functions.
1061 	 */
1062 	int	(*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
1063 		    bus_size_t, bus_dma_segment_t *, int, int *, int));
1064 	void	(*_dmamem_free) __P((bus_dma_tag_t,
1065 		    bus_dma_segment_t *, int));
1066 	int	(*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
1067 		    int, size_t, caddr_t *, int));
1068 	void	(*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
1069 	paddr_t	(*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
1070 		    int, off_t, int, int));
1071 };
1072 
1073 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
1074 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
1075 #define	bus_dmamap_destroy(t, p)				\
1076 	(*(t)->_dmamap_destroy)((t), (p))
1077 #define	bus_dmamap_load(t, m, b, s, p, f)			\
1078 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
1079 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
1080 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
1081 #define	bus_dmamap_load_uio(t, m, u, f)				\
1082 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
1083 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
1084 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
1085 #define	bus_dmamap_unload(t, p)					\
1086 	(*(t)->_dmamap_unload)((t), (p))
1087 #define	bus_dmamap_sync(t, p, o, l, ops)			\
1088 	(void)((t)->_dmamap_sync ?				\
1089 	    (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
1090 
1091 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
1092 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
1093 #define	bus_dmamem_free(t, sg, n)				\
1094 	(*(t)->_dmamem_free)((t), (sg), (n))
1095 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
1096 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
1097 #define	bus_dmamem_unmap(t, k, s)				\
1098 	(*(t)->_dmamem_unmap)((t), (k), (s))
1099 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
1100 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
1101 
1102 /*
1103  *	bus_dmamap_t
1104  *
1105  *	Describes a DMA mapping.
1106  */
1107 struct prep_bus_dmamap {
1108 	/*
1109 	 * PRIVATE MEMBERS: not for use my machine-independent code.
1110 	 */
1111 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
1112 	int		_dm_segcnt;	/* number of segs this map can map */
1113 	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
1114 	bus_size_t	_dm_boundary;	/* don't cross this */
1115 	bus_addr_t	_dm_bounce_thresh; /* bounce threshold; see tag */
1116 	int		_dm_flags;	/* misc. flags */
1117 
1118 	void		*_dm_cookie;	/* cookie for bus-specific functions */
1119 
1120 	/*
1121 	 * PUBLIC MEMBERS: these are used by machine-independent code.
1122 	 */
1123 	bus_size_t	dm_mapsize;	/* size of the mapping */
1124 	int		dm_nsegs;	/* # valid segments in mapping */
1125 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
1126 };
1127 
1128 #ifdef _PREP_BUS_DMA_PRIVATE
1129 int	_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
1130 	    bus_size_t, int, bus_dmamap_t *));
1131 void	_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
1132 int	_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
1133 	    bus_size_t, struct proc *, int));
1134 int	_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
1135 	    struct mbuf *, int));
1136 int	_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
1137 	    struct uio *, int));
1138 int	_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
1139 	    bus_dma_segment_t *, int, bus_size_t, int));
1140 void	_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
1141 void	_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
1142 	    bus_size_t, int));
1143 
1144 int	_bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
1145 	    bus_size_t alignment, bus_size_t boundary,
1146 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
1147 void	_bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1148 	    int nsegs));
1149 int	_bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1150 	    int nsegs, size_t size, caddr_t *kvap, int flags));
1151 void	_bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
1152 	    size_t size));
1153 paddr_t	_bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
1154 	    int nsegs, off_t off, int prot, int flags));
1155 
1156 int	_bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
1157 	    bus_size_t alignment, bus_size_t boundary,
1158 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
1159 	    paddr_t low, paddr_t high));
1160 #endif /* _PREP_BUS_DMA_PRIVATE */
1161 #endif /* _PREP_BUS_H_ */
1162