xref: /freebsd/sys/powerpc/include/bus.h (revision b52b9d56d4e96089873a75f9e29062eec19fabba)
1 /*-
2  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
7  * NASA Ames Research Center.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *	This product includes software developed by the NetBSD
20  *	Foundation, Inc. and its contributors.
21  * 4. Neither the name of The NetBSD Foundation nor the names of its
22  *    contributors may be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 /*
39  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
40  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
41  *
42  * Redistribution and use in source and binary forms, with or without
43  * modification, are permitted provided that the following conditions
44  * are met:
45  * 1. Redistributions of source code must retain the above copyright
46  *    notice, this list of conditions and the following disclaimer.
47  * 2. Redistributions in binary form must reproduce the above copyright
48  *    notice, this list of conditions and the following disclaimer in the
49  *    documentation and/or other materials provided with the distribution.
50  * 3. All advertising materials mentioning features or use of this software
51  *    must display the following acknowledgement:
52  *      This product includes software developed by Christopher G. Demetriou
53  *	for the NetBSD Project.
54  * 4. The name of the author may not be used to endorse or promote products
55  *    derived from this software without specific prior written permission
56  *
57  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
58  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
59  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
60  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
61  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
62  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
63  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
64  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
65  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
66  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67  *
68  *	$NetBSD: bus.h,v 1.9.4.1 2000/06/30 16:27:30 simonb Exp $
69  * $FreeBSD$
70  */
71 
72 #ifndef	_MACPPC_BUS_H_
73 #define	_MACPPC_BUS_H_
74 
75 #include <machine/pio.h>
76 
77 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
78 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
79 #define BUS_SPACE_MAXSIZE       (128 * 1024) /* Maximum supported size */
80 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
81 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
82 #define BUS_SPACE_MAXADDR       0xFFFFFFFF
83 
84 #define BUS_SPACE_UNRESTRICTED  (~0)
85 
86 /*
87  * Values for the macppc bus space tag, not to be used directly by MI code.
88  */
89 
90 #define	__BUS_SPACE_HAS_STREAM_METHODS
91 
92 /*
93  * Values for the ppc bus space tag, not to be used directly by MI code.
94  */
95 #define PPC_BUS_SPACE_MEM      1       /* space is mem space */
96 
97 
98 #define	__BA(t, h, o) ((void *)((h) + (o)))
99 
100 /*
101  * Bus address and size types
102  */
103 typedef u_int32_t bus_addr_t;
104 typedef u_int32_t bus_size_t;
105 
106 /*
107  * Access methods for bus resources and address space.
108  */
109 typedef u_int32_t bus_space_tag_t;
110 typedef u_int32_t bus_space_handle_t;
111 
112 static __inline void *
113 __ppc_ba(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset)
114 {
115 	return ((void *)(handle + offset));
116 }
117 
118 
119 /*
120  *	int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
121  *	    bus_size_t size, int flags, bus_space_handle_t *bshp));
122  *
123  * Map a region of bus space.
124  */
125 #if 0
126 bus_space_map(t, addr, size, flags, bshp) ! not implemented !
127 #endif
128 
129 /*
130  *	int bus_space_unmap(bus_space_tag_t t,
131  *	    bus_space_handle_t bsh, bus_size_t size));
132  *
133  * Unmap a region of bus space.
134  */
135 
136 #define bus_space_unmap(t, bsh, size)
137 
138 /*
139  *	int bus_space_subregion(bus_space_tag_t t,
140  *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
141  *	    bus_space_handle_t *nbshp));
142  *
143  * Get a new handle for a subregion of an already-mapped area of bus space.
144  */
145 
146 #define	bus_space_subregion(t, bsh, offset, size, bshp)			\
147 	((*(bshp) = (bus_space_handle_t)__ppc_ba(t, bsh, offset)), 0)
148 
149 /*
150  *	int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
151  *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
152  *	    bus_size_t boundary, int flags, bus_addr_t *addrp,
153  *	    bus_space_handle_t *bshp));
154  *
155  * Allocate a region of bus space.
156  */
157 
158 #if 0
159 #define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)	!!! unimplemented !!!
160 #endif
161 
162 /*
163  *	int bus_space_free(bus_space_tag_t t,
164  *	    bus_space_handle_t bsh, bus_size_t size));
165  *
166  * Free a region of bus space.
167  */
168 #if 0
169 #define	bus_space_free(t, h, s)		!!! unimplemented !!!
170 #endif
171 
172 /*
173  *	u_intN_t bus_space_read_N(bus_space_tag_t tag,
174  *	    bus_space_handle_t bsh, bus_size_t offset));
175  *
176  * Read a 1, 2, 4, or 8 byte quantity from bus space
177  * described by tag/handle/offset.
178  */
179 
180 #define	bus_space_read_1(t, h, o)	(in8(__ppc_ba(t, h, o)))
181 #define	bus_space_read_2(t, h, o)	(in16rb(__ppc_ba(t, h, o)))
182 #define	bus_space_read_4(t, h, o)	(in32rb(__ppc_ba(t, h, o)))
183 #if 0	/* Cause a link error for bus_space_read_8 */
184 #define	bus_space_read_8(t, h, o)	!!! unimplemented !!!
185 #endif
186 
187 #define	bus_space_read_stream_1(t, h, o)	(in8(__ppc_ba(t, h, o)))
188 #define	bus_space_read_stream_2(t, h, o)	(in16(__ppc_ba(t, h, o)))
189 #define	bus_space_read_stream_4(t, h, o)	(in32(__ppc_ba(t, h, o)))
190 #if 0	/* Cause a link error for bus_space_read_stream_8 */
191 #define	bus_space_read_8(t, h, o)	!!! unimplemented !!!
192 #endif
193 
194 /*
195  *	void bus_space_read_multi_N(bus_space_tag_t tag,
196  *	    bus_space_handle_t bsh, bus_size_t offset,
197  *	    u_intN_t *addr, size_t count));
198  *
199  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
200  * described by tag/handle/offset and copy into buffer provided.
201  */
202 
203 #define	bus_space_read_multi_1(t, h, o, a, c) do {			\
204 		ins8(__ppc_ba(t, h, o), (a), (c));		       	\
205 	} while (0)
206 
207 #define	bus_space_read_multi_2(t, h, o, a, c) do {			\
208 		ins16rb(__ppc_ba(t, h, o), (a), (c));			\
209 	} while (0)
210 
211 #define	bus_space_read_multi_4(t, h, o, a, c) do {			\
212 		ins32rb(__ppc_ba(t, h, o), (a), (c));			\
213 	} while (0)
214 
215 #if 0	/* Cause a link error for bus_space_read_multi_8 */
216 #define	bus_space_read_multi_8		!!! unimplemented !!!
217 #endif
218 
219 #define	bus_space_read_multi_stream_1(t, h, o, a, c) do {		\
220 		ins8(__ppc_ba(t, h, o), (a), (c));		       	\
221 	} while (0)
222 
223 #define	bus_space_read_multi_stream_2(t, h, o, a, c) do {		\
224 		ins16(__ppc_ba(t, h, o), (a), (c));		       	\
225 	} while (0)
226 
227 #define	bus_space_read_multi_stream_4(t, h, o, a, c) do {		\
228 		ins32(__ppc_ba(t, h, o), (a), (c));		       	\
229 	} while (0)
230 
231 #if 0	/* Cause a link error for bus_space_read_multi_stream_8 */
232 #define	bus_space_read_multi_stream_8	!!! unimplemented !!!
233 #endif
234 
235 /*
236  *	void bus_space_read_region_N(bus_space_tag_t tag,
237  *	    bus_space_handle_t bsh, bus_size_t offset,
238  *	    u_intN_t *addr, size_t count));
239  *
240  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
241  * described by tag/handle and starting at `offset' and copy into
242  * buffer provided.
243  */
244 
245 static __inline void
246 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
247     bus_size_t offset, u_int8_t *addr, size_t count)
248 {
249 	volatile u_int8_t *s = __ppc_ba(tag, bsh, offset);
250 
251 	while (count--)
252 		*addr++ = *s++;
253 	__asm __volatile("eieio; sync");
254 }
255 
256 static __inline void
257 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
258     bus_size_t offset, u_int16_t *addr, size_t count)
259 {
260 	volatile u_int16_t *s = __ppc_ba(tag, bsh, offset);
261 
262 	while (count--)
263 		__asm __volatile("lhbrx %0, 0, %1" :
264 			"=r"(*addr++) : "r"(s++));
265 	__asm __volatile("eieio; sync");
266 }
267 
268 static __inline void
269 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
270     bus_size_t offset, u_int32_t *addr, size_t count)
271 {
272 	volatile u_int32_t *s = __ppc_ba(tag, bsh, offset);
273 
274 	while (count--)
275 		__asm __volatile("lwbrx %0, 0, %1" :
276 			"=r"(*addr++) : "r"(s++));
277 	__asm __volatile("eieio; sync");
278 }
279 
280 #if 0	/* Cause a link error for bus_space_read_region_8 */
281 #define	bus_space_read_region_8		!!! unimplemented !!!
282 #endif
283 
284 static __inline void
285 bus_space_read_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
286     bus_size_t offset, u_int16_t *addr, size_t count)
287 {
288 	volatile u_int16_t *s = __ppc_ba(tag, bsh, offset);
289 
290 	while (count--)
291 		*addr++ = *s++;
292 	__asm __volatile("eieio; sync");
293 }
294 
295 static __inline void
296 bus_space_read_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
297     bus_size_t offset, u_int32_t *addr, size_t count)
298 {
299 	volatile u_int32_t *s = __ppc_ba(tag, bsh, offset);
300 
301 	while (count--)
302 		*addr++ = *s++;
303 	__asm __volatile("eieio; sync");
304 }
305 
306 #if 0	/* Cause a link error */
307 #define	bus_space_read_region_stream_8		!!! unimplemented !!!
308 #endif
309 
310 /*
311  *	void bus_space_write_N(bus_space_tag_t tag,
312  *	    bus_space_handle_t bsh, bus_size_t offset,
313  *	    u_intN_t value));
314  *
315  * Write the 1, 2, 4, or 8 byte value `value' to bus space
316  * described by tag/handle/offset.
317  */
318 
319 #define bus_space_write_1(t, h, o, v)	out8(__ppc_ba(t, h, o), (v))
320 #define bus_space_write_2(t, h, o, v)	out16rb(__ppc_ba(t, h, o), (v))
321 #define bus_space_write_4(t, h, o, v)	out32rb(__ppc_ba(t, h, o), (v))
322 
323 #define bus_space_write_stream_1(t, h, o, v)	out8(__ppc_ba(t, h, o), (v))
324 #define bus_space_write_stream_2(t, h, o, v)	out16(__ppc_ba(t, h, o), (v))
325 #define bus_space_write_stream_4(t, h, o, v)	out32(__ppc_ba(t, h, o), (v))
326 
327 #if 0	/* Cause a link error for bus_space_write_8 */
328 #define bus_space_write_8		!!! unimplemented !!!
329 #endif
330 
331 /*
332  *	void bus_space_write_multi_N(bus_space_tag_t tag,
333  *	    bus_space_handle_t bsh, bus_size_t offset,
334  *	    const u_intN_t *addr, size_t count));
335  *
336  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
337  * provided to bus space described by tag/handle/offset.
338  */
339 
340 #define bus_space_write_multi_1(t, h, o, a, c) do {			\
341 		outsb(__ppc_ba(t, h, o), (a), (c));		       	\
342 	} while (0)
343 
344 #define bus_space_write_multi_2(t, h, o, a, c) do {			\
345 		outsw(__ppc_ba(t, h, o), (a), (c));		       	\
346 	} while (0)
347 
348 #define bus_space_write_multi_4(t, h, o, a, c) do {			\
349 		outsl(__ppc_ba(t, h, o), (a), (c));		       	\
350 	} while (0)
351 
352 #if 0
353 #define bus_space_write_multi_8		!!! unimplemented !!!
354 #endif
355 
356 #define bus_space_write_multi_stream_2(t, h, o, a, c) do {		\
357 		outsw(__ppc_ba(t, h, o), (a), (c));		       	\
358 	} while (0)
359 
360 #define bus_space_write_multi_stream_4(t, h, o, a, c) do {		\
361 		outsl(__ppc_ba(t, h, o), (a), (c));		       	\
362 	} while (0)
363 
364 #if 0
365 #define bus_space_write_multi_stream_8	!!! unimplemented !!!
366 #endif
367 
368 /*
369  *	void bus_space_write_region_N(bus_space_tag_t tag,
370  *	    bus_space_handle_t bsh, bus_size_t offset,
371  *	    const u_intN_t *addr, size_t count));
372  *
373  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
374  * to bus space described by tag/handle starting at `offset'.
375  */
376 
377 static __inline void
378 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
379     bus_size_t offset, const u_int8_t *addr, size_t count)
380 {
381 	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
382 
383 	while (count--)
384 		*d++ = *addr++;
385 	__asm __volatile("eieio; sync");
386 }
387 
388 static __inline void
389 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
390     bus_size_t offset, const u_int16_t *addr, size_t count)
391 {
392 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
393 
394 	while (count--)
395 		__asm __volatile("sthbrx %0, 0, %1" ::
396 			"r"(*addr++), "r"(d++));
397 	__asm __volatile("eieio; sync");
398 }
399 
400 static __inline void
401 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
402     bus_size_t offset, const u_int32_t *addr, size_t count)
403 {
404 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
405 
406 	while (count--)
407 		__asm __volatile("stwbrx %0, 0, %1" ::
408 			"r"(*addr++), "r"(d++));
409 	__asm __volatile("eieio; sync");
410 }
411 
412 #if 0
413 #define	bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!!
414 #endif
415 
416 static __inline void
417 bus_space_write_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
418     bus_size_t offset, const u_int16_t *addr, size_t count)
419 {
420 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
421 
422 	while (count--)
423 		*d++ = *addr++;
424 	__asm __volatile("eieio; sync");
425 }
426 
427 static __inline void
428 bus_space_write_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
429     bus_size_t offset, const u_int32_t *addr, size_t count)
430 {
431 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
432 
433 	while (count--)
434 		*d++ = *addr++;
435 	__asm __volatile("eieio; sync");
436 }
437 
438 #if 0
439 #define	bus_space_write_region_stream_8	!!! unimplemented !!!
440 #endif
441 
442 /*
443  *	void bus_space_set_multi_N(bus_space_tag_t tag,
444  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
445  *	    size_t count));
446  *
447  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
448  * by tag/handle/offset `count' times.
449  */
450 
451 static __inline void
452 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
453     bus_size_t offset, u_int8_t val, size_t count)
454 {
455 	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
456 
457 	while (count--)
458 		*d = val;
459 	__asm __volatile("eieio; sync");
460 }
461 
462 static __inline void
463 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
464     bus_size_t offset, u_int16_t val, size_t count)
465 {
466 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
467 
468 	while (count--)
469 		__asm __volatile("sthbrx %0, 0, %1" ::
470 			"r"(val), "r"(d));
471 	__asm __volatile("eieio; sync");
472 }
473 
474 static __inline void
475 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
476     bus_size_t offset, u_int32_t val, size_t count)
477 {
478 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
479 
480 	while (count--)
481 		__asm __volatile("stwbrx %0, 0, %1" ::
482 			"r"(val), "r"(d));
483 	__asm __volatile("eieio; sync");
484 }
485 
486 #if 0
487 #define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
488 #endif
489 
490 static __inline void
491 bus_space_set_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
492     bus_size_t offset, u_int16_t val, size_t count)
493 {
494 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
495 
496 	while (count--)
497 		*d = val;
498 	__asm __volatile("eieio; sync");
499 }
500 
501 static __inline void
502 bus_space_set_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
503     bus_size_t offset, u_int32_t val, size_t count)
504 {
505 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
506 
507 	while (count--)
508 		*d = val;
509 	__asm __volatile("eieio; sync");
510 }
511 
512 #if 0
513 #define	bus_space_set_multi_stream_8	!!! unimplemented !!!
514 #endif
515 
516 /*
517  *	void bus_space_set_region_N(bus_space_tag_t tag,
518  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
519  *	    size_t count));
520  *
521  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
522  * by tag/handle starting at `offset'.
523  */
524 
525 static __inline void
526 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
527     bus_size_t offset, u_int8_t val, size_t count)
528 {
529 	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
530 
531 	while (count--)
532 		*d++ = val;
533 	__asm __volatile("eieio; sync");
534 }
535 
536 static __inline void
537 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
538     bus_size_t offset, u_int16_t val, size_t count)
539 {
540 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
541 
542 	while (count--)
543 		__asm __volatile("sthbrx %0, 0, %1" ::
544 			"r"(val), "r"(d++));
545 	__asm __volatile("eieio; sync");
546 }
547 
548 static __inline void
549 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
550     bus_size_t offset, u_int32_t val, size_t count)
551 {
552 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
553 
554 	while (count--)
555 		__asm __volatile("stwbrx %0, 0, %1" ::
556 			"r"(val), "r"(d++));
557 	__asm __volatile("eieio; sync");
558 }
559 
560 #if 0
561 #define	bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
562 #endif
563 
564 static __inline void
565 bus_space_set_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
566     bus_size_t offset, u_int16_t val, size_t count)
567 {
568 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
569 
570 	while (count--)
571 		*d++ = val;
572 	__asm __volatile("eieio; sync");
573 }
574 
575 static __inline void
576 bus_space_set_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
577     bus_size_t offset, u_int32_t val, size_t count)
578 {
579 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
580 
581 	while (count--)
582 		*d++ = val;
583 	__asm __volatile("eieio; sync");
584 }
585 
586 #if 0
587 #define	bus_space_set_region_stream_8	!!! unimplemented !!!
588 #endif
589 
590 /*
591  *	void bus_space_copy_region_N(bus_space_tag_t tag,
592  *	    bus_space_handle_t bsh1, bus_size_t off1,
593  *	    bus_space_handle_t bsh2, bus_size_t off2,
594  *	    size_t count));
595  *
596  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
597  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
598  */
599 
600 	/* XXX IMPLEMENT bus_space_copy_N() XXX */
601 
602 /*
603  * Bus read/write barrier methods.
604  *
605  *	void bus_space_barrier(bus_space_tag_t tag,
606  *	    bus_space_handle_t bsh, bus_size_t offset,
607  *	    bus_size_t len, int flags));
608  *
609  * Note: the macppc does not currently require barriers, but we must
610  * provide the flags to MI code.
611  */
612 
613 #define bus_space_barrier(t, h, o, l, f)	\
614 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
615 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
616 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
617 
618 #define	BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
619 
620 /*
621  * Bus DMA methods.
622  */
623 
624 /*
625  * Flags used in various bus DMA methods.
626  */
627 #define	BUS_DMA_WAITOK		0x00	/* safe to sleep (pseudo-flag) */
628 #define	BUS_DMA_NOWAIT		0x01	/* not safe to sleep */
629 #define	BUS_DMA_ALLOCNOW	0x02	/* perform resource allocation now */
630 #define	BUS_DMA_COHERENT	0x04	/* hint: map memory DMA coherent */
631 #define	BUS_DMA_BUS1		0x10	/* placeholders for bus functions... */
632 #define	BUS_DMA_BUS2		0x20
633 #define	BUS_DMA_BUS3		0x40
634 #define	BUS_DMA_BUS4		0x80
635 
636 /* Forwards needed by prototypes below. */
637 struct mbuf;
638 struct uio;
639 
640 /*
641  *      bus_dmasync_op_t
642  *
643  *      Operations performed by bus_dmamap_sync().
644  */
645 typedef enum {
646 	BUS_DMASYNC_PREREAD,
647 	BUS_DMASYNC_POSTREAD,
648 	BUS_DMASYNC_PREWRITE,
649 	BUS_DMASYNC_POSTWRITE
650 } bus_dmasync_op_t;
651 
652 /*
653  *      bus_dma_tag_t
654  *
655  *      A machine-dependent opaque type describing the characteristics
656  *      of how to perform DMA mappings.  This structure encapsultes
657  *      information concerning address and alignment restrictions, number
658  *      of S/G  segments, amount of data per S/G segment, etc.
659  */
660 typedef struct bus_dma_tag	*bus_dma_tag_t;
661 
662 /*
663  *      bus_dmamap_t
664  *
665  *      DMA mapping instance information.
666  */
667 typedef struct bus_dmamap	*bus_dmamap_t;
668 
669 /*
670  *	bus_dma_segment_t
671  *
672  *	Describes a single contiguous DMA transaction.  Values
673  *	are suitable for programming into DMA registers.
674  */
675 typedef struct bus_dma_segment {
676 	bus_addr_t	ds_addr;	/* DMA address */
677 	bus_size_t	ds_len;		/* length of transfer */
678 } bus_dma_segment_t;
679 
680 /*
681  * A function that returns 1 if the address cannot be accessed by
682  * a device and 0 if it can be.
683  */
684 typedef int bus_dma_filter_t(void *, bus_addr_t);
685 
686 /*
687  * Allocate a device specific dma_tag encapsulating the constraints of
688  * the parent tag in addition to other restrictions specified:
689  *
690  *      alignment:      alignment for segments.
691  *      boundary:       Boundary that segments cannot cross.
692  *      lowaddr:        Low restricted address that cannot appear in a mapping.
693  *      highaddr:       High restricted address that cannot appear in a mapping.
694  *      filtfunc:       An optional function to further test if an address
695  *                      within the range of lowaddr and highaddr cannot appear
696  *                      in a mapping.
697  *      filtfuncarg:    An argument that will be passed to filtfunc in addition
698  *                      to the address to test.
699  *      maxsize:        Maximum mapping size supported by this tag.
700  *      nsegments:      Number of discontinuities allowed in maps.
701  *      maxsegsz:       Maximum size of a segment in the map.
702  *      flags:          Bus DMA flags.
703  *      dmat:           A pointer to set to a valid dma tag should the return
704  *                      value of this function indicate success.
705  */
706 int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
707 		       bus_size_t boundary, bus_addr_t lowaddr,
708 		       bus_addr_t highaddr, bus_dma_filter_t *filtfunc,
709 		       void *filtfuncarg, bus_size_t maxsize, int nsegments,
710 		       bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat);
711 
712 int bus_dma_tag_destroy(bus_dma_tag_t dmat);
713 
714 /*
715  * Allocate a handle for mapping from kva/uva/physical
716  * address space into bus device space.
717  */
718 int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp);
719 
720 /*
721  * Destroy  a handle for mapping from kva/uva/physical
722  * address space into bus device space.
723  */
724 int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map);
725 
726 /*
727  * Allocate a piece of memory that can be efficiently mapped into
728  * bus device space based on the constraints lited in the dma tag.
729  * A dmamap to for use with dmamap_load is also allocated.
730  */
731 int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
732 		     bus_dmamap_t *mapp);
733 
734 /*
735  * Free a piece of memory and it's allociated dmamap, that was allocated
736  * via bus_dmamem_alloc.
737  */
738 void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map);
739 
740 /*
741  * A function that processes a successfully loaded dma map or an error
742  * from a delayed load map.
743  */
744 typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
745 
746 /*
747  * Map the buffer buf into bus space using the dmamap map.
748  */
749 int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
750 		    bus_size_t buflen, bus_dmamap_callback_t *callback,
751 		    void *callback_arg, int flags);
752 
753 /*
754  * Perform a syncronization operation on the given map.
755  */
756 void bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t);
757 
758 /*
759  * Release the mapping held by map.
760  */
761 void bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map);
762 
763 #endif /* _MACPPC_BUS_H_ */
764