xref: /freebsd/sys/powerpc/include/bus.h (revision 1b6c76a2fe091c74f08427e6c870851025a9cf67)
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 /*
78  * Values for the macppc bus space tag, not to be used directly by MI code.
79  */
80 
81 #define	__BUS_SPACE_HAS_STREAM_METHODS
82 
83 #define	MACPPC_BUS_ADDR_MASK	0xfffff000
84 #define	MACPPC_BUS_STRIDE_MASK	0x0000000f
85 
86 #define macppc_make_bus_space_tag(addr, stride) \
87 	(((addr) & MACPPC_BUS_ADDR_MASK) | (stride))
88 #define	__BA(t, h, o) ((void *)((h) + ((o) << ((t) & MACPPC_BUS_STRIDE_MASK))))
89 
90 /*
91  * Bus address and size types
92  */
93 typedef u_int32_t bus_addr_t;
94 typedef u_int32_t bus_size_t;
95 
96 /*
97  * Access methods for bus resources and address space.
98  */
99 typedef u_int32_t bus_space_tag_t;
100 typedef u_int32_t bus_space_handle_t;
101 
102 /*
103  *	int bus_space_map  __P((bus_space_tag_t t, bus_addr_t addr,
104  *	    bus_size_t size, int flags, bus_space_handle_t *bshp));
105  *
106  * Map a region of bus space.
107  */
108 
109 #define	BUS_SPACE_MAP_CACHEABLE		0x01
110 #define	BUS_SPACE_MAP_LINEAR		0x02
111 #define	BUS_SPACE_MAP_PREFETCHABLE	0x04
112 
113 extern void *mapiodev(vm_offset_t, vm_size_t);
114 
115 static __inline int
116 bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size, int flags,
117     bus_space_handle_t *bshp)
118 {
119 	vm_offset_t base = t & MACPPC_BUS_ADDR_MASK;
120 	int stride = t & MACPPC_BUS_STRIDE_MASK;
121 
122 	*bshp = (bus_space_handle_t)
123 		mapiodev(base + (addr << stride), size << stride);
124 	return 0;
125 }
126 
127 /*
128  *	int bus_space_unmap __P((bus_space_tag_t t,
129  *	    bus_space_handle_t bsh, bus_size_t size));
130  *
131  * Unmap a region of bus space.
132  */
133 
134 #define bus_space_unmap(t, bsh, size)
135 
136 /*
137  *	int bus_space_subregion __P((bus_space_tag_t t,
138  *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
139  *	    bus_space_handle_t *nbshp));
140  *
141  * Get a new handle for a subregion of an already-mapped area of bus space.
142  */
143 
144 #define	bus_space_subregion(t, bsh, offset, size, bshp)			\
145 	((*(bshp) = (bus_space_handle_t)__BA(t, bsh, offset)), 0)
146 
147 /*
148  *	int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
149  *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
150  *	    bus_size_t boundary, int flags, bus_addr_t *addrp,
151  *	    bus_space_handle_t *bshp));
152  *
153  * Allocate a region of bus space.
154  */
155 
156 #if 0
157 #define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)	!!! unimplemented !!!
158 #endif
159 
160 /*
161  *	int bus_space_free __P((bus_space_tag_t t,
162  *	    bus_space_handle_t bsh, bus_size_t size));
163  *
164  * Free a region of bus space.
165  */
166 #if 0
167 #define	bus_space_free(t, h, s)		!!! unimplemented !!!
168 #endif
169 
170 /*
171  *	u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
172  *	    bus_space_handle_t bsh, bus_size_t offset));
173  *
174  * Read a 1, 2, 4, or 8 byte quantity from bus space
175  * described by tag/handle/offset.
176  */
177 
178 #define	bus_space_read_1(t, h, o)	(in8(__BA(t, h, o)))
179 #define	bus_space_read_2(t, h, o)	(in16rb(__BA(t, h, o)))
180 #define	bus_space_read_4(t, h, o)	(in32rb(__BA(t, h, o)))
181 #if 0	/* Cause a link error for bus_space_read_8 */
182 #define	bus_space_read_8(t, h, o)	!!! unimplemented !!!
183 #endif
184 
185 #define	bus_space_read_stream_1(t, h, o)	(in8(__BA(t, h, o)))
186 #define	bus_space_read_stream_2(t, h, o)	(in16(__BA(t, h, o)))
187 #define	bus_space_read_stream_4(t, h, o)	(in32(__BA(t, h, o)))
188 #if 0	/* Cause a link error for bus_space_read_stream_8 */
189 #define	bus_space_read_8(t, h, o)	!!! unimplemented !!!
190 #endif
191 
192 /*
193  *	void bus_space_read_multi_N __P((bus_space_tag_t tag,
194  *	    bus_space_handle_t bsh, bus_size_t offset,
195  *	    u_intN_t *addr, size_t count));
196  *
197  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
198  * described by tag/handle/offset and copy into buffer provided.
199  */
200 
201 #define	bus_space_read_multi_1(t, h, o, a, c) do {			\
202 		ins8(__BA(t, h, o), (a), (c));				\
203 	} while (0)
204 
205 #define	bus_space_read_multi_2(t, h, o, a, c) do {			\
206 		ins16rb(__BA(t, h, o), (a), (c));			\
207 	} while (0)
208 
209 #define	bus_space_read_multi_4(t, h, o, a, c) do {			\
210 		ins32rb(__BA(t, h, o), (a), (c));			\
211 	} while (0)
212 
213 #if 0	/* Cause a link error for bus_space_read_multi_8 */
214 #define	bus_space_read_multi_8		!!! unimplemented !!!
215 #endif
216 
217 #define	bus_space_read_multi_stream_1(t, h, o, a, c) do {		\
218 		ins8(__BA(t, h, o), (a), (c));				\
219 	} while (0)
220 
221 #define	bus_space_read_multi_stream_2(t, h, o, a, c) do {		\
222 		ins16(__BA(t, h, o), (a), (c));				\
223 	} while (0)
224 
225 #define	bus_space_read_multi_stream_4(t, h, o, a, c) do {		\
226 		ins32(__BA(t, h, o), (a), (c));				\
227 	} while (0)
228 
229 #if 0	/* Cause a link error for bus_space_read_multi_stream_8 */
230 #define	bus_space_read_multi_stream_8	!!! unimplemented !!!
231 #endif
232 
233 /*
234  *	void bus_space_read_region_N __P((bus_space_tag_t tag,
235  *	    bus_space_handle_t bsh, bus_size_t offset,
236  *	    u_intN_t *addr, size_t count));
237  *
238  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
239  * described by tag/handle and starting at `offset' and copy into
240  * buffer provided.
241  */
242 
243 static __inline void
244 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
245     bus_size_t offset, u_int8_t *addr, size_t count)
246 {
247 	volatile u_int8_t *s = __BA(tag, bsh, offset);
248 
249 	while (count--)
250 		*addr++ = *s++;
251 	__asm __volatile("eieio; sync");
252 }
253 
254 static __inline void
255 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
256     bus_size_t offset, u_int16_t *addr, size_t count)
257 {
258 	volatile u_int16_t *s = __BA(tag, bsh, offset);
259 
260 	while (count--)
261 		__asm __volatile("lhbrx %0, 0, %1" :
262 			"=r"(*addr++) : "r"(s++));
263 	__asm __volatile("eieio; sync");
264 }
265 
266 static __inline void
267 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
268     bus_size_t offset, u_int32_t *addr, size_t count)
269 {
270 	volatile u_int32_t *s = __BA(tag, bsh, offset);
271 
272 	while (count--)
273 		__asm __volatile("lwbrx %0, 0, %1" :
274 			"=r"(*addr++) : "r"(s++));
275 	__asm __volatile("eieio; sync");
276 }
277 
278 #if 0	/* Cause a link error for bus_space_read_region_8 */
279 #define	bus_space_read_region_8		!!! unimplemented !!!
280 #endif
281 
282 static __inline void
283 bus_space_read_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
284     bus_size_t offset, u_int16_t *addr, size_t count)
285 {
286 	volatile u_int16_t *s = __BA(tag, bsh, offset);
287 
288 	while (count--)
289 		*addr++ = *s++;
290 	__asm __volatile("eieio; sync");
291 }
292 
293 static __inline void
294 bus_space_read_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
295     bus_size_t offset, u_int32_t *addr, size_t count)
296 {
297 	volatile u_int32_t *s = __BA(tag, bsh, offset);
298 
299 	while (count--)
300 		*addr++ = *s++;
301 	__asm __volatile("eieio; sync");
302 }
303 
304 #if 0	/* Cause a link error */
305 #define	bus_space_read_region_stream_8		!!! unimplemented !!!
306 #endif
307 
308 /*
309  *	void bus_space_write_N __P((bus_space_tag_t tag,
310  *	    bus_space_handle_t bsh, bus_size_t offset,
311  *	    u_intN_t value));
312  *
313  * Write the 1, 2, 4, or 8 byte value `value' to bus space
314  * described by tag/handle/offset.
315  */
316 
317 #define bus_space_write_1(t, h, o, v)	out8(__BA(t, h, o), (v))
318 #define bus_space_write_2(t, h, o, v)	out16rb(__BA(t, h, o), (v))
319 #define bus_space_write_4(t, h, o, v)	out32rb(__BA(t, h, o), (v))
320 
321 #define bus_space_write_stream_1(t, h, o, v)	out8(__BA(t, h, o), (v))
322 #define bus_space_write_stream_2(t, h, o, v)	out16(__BA(t, h, o), (v))
323 #define bus_space_write_stream_4(t, h, o, v)	out32(__BA(t, h, o), (v))
324 
325 #if 0	/* Cause a link error for bus_space_write_8 */
326 #define bus_space_write_8		!!! unimplemented !!!
327 #endif
328 
329 /*
330  *	void bus_space_write_multi_N __P((bus_space_tag_t tag,
331  *	    bus_space_handle_t bsh, bus_size_t offset,
332  *	    const u_intN_t *addr, size_t count));
333  *
334  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
335  * provided to bus space described by tag/handle/offset.
336  */
337 
338 #define bus_space_write_multi_1(t, h, o, a, c) do {			\
339 		outsb(__BA(t, h, o), (a), (c));				\
340 	} while (0)
341 
342 #define bus_space_write_multi_2(t, h, o, a, c) do {			\
343 		outsw(__BA(t, h, o), (a), (c));				\
344 	} while (0)
345 
346 #define bus_space_write_multi_4(t, h, o, a, c) do {			\
347 		outsl(__BA(t, h, o), (a), (c));				\
348 	} while (0)
349 
350 #if 0
351 #define bus_space_write_multi_8		!!! unimplemented !!!
352 #endif
353 
354 #define bus_space_write_multi_stream_2(t, h, o, a, c) do {		\
355 		outsw(__BA(t, h, o), (a), (c));				\
356 	} while (0)
357 
358 #define bus_space_write_multi_stream_4(t, h, o, a, c) do {		\
359 		outsl(__BA(t, h, o), (a), (c));				\
360 	} while (0)
361 
362 #if 0
363 #define bus_space_write_multi_stream_8	!!! unimplemented !!!
364 #endif
365 
366 /*
367  *	void bus_space_write_region_N __P((bus_space_tag_t tag,
368  *	    bus_space_handle_t bsh, bus_size_t offset,
369  *	    const u_intN_t *addr, size_t count));
370  *
371  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
372  * to bus space described by tag/handle starting at `offset'.
373  */
374 
375 static __inline void
376 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
377     bus_size_t offset, const u_int8_t *addr, size_t count)
378 {
379 	volatile u_int8_t *d = __BA(tag, bsh, offset);
380 
381 	while (count--)
382 		*d++ = *addr++;
383 	__asm __volatile("eieio; sync");
384 }
385 
386 static __inline void
387 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
388     bus_size_t offset, const u_int16_t *addr, size_t count)
389 {
390 	volatile u_int16_t *d = __BA(tag, bsh, offset);
391 
392 	while (count--)
393 		__asm __volatile("sthbrx %0, 0, %1" ::
394 			"r"(*addr++), "r"(d++));
395 	__asm __volatile("eieio; sync");
396 }
397 
398 static __inline void
399 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
400     bus_size_t offset, const u_int32_t *addr, size_t count)
401 {
402 	volatile u_int32_t *d = __BA(tag, bsh, offset);
403 
404 	while (count--)
405 		__asm __volatile("stwbrx %0, 0, %1" ::
406 			"r"(*addr++), "r"(d++));
407 	__asm __volatile("eieio; sync");
408 }
409 
410 #if 0
411 #define	bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!!
412 #endif
413 
414 static __inline void
415 bus_space_write_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
416     bus_size_t offset, const u_int16_t *addr, size_t count)
417 {
418 	volatile u_int16_t *d = __BA(tag, bsh, offset);
419 
420 	while (count--)
421 		*d++ = *addr++;
422 	__asm __volatile("eieio; sync");
423 }
424 
425 static __inline void
426 bus_space_write_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
427     bus_size_t offset, const u_int32_t *addr, size_t count)
428 {
429 	volatile u_int32_t *d = __BA(tag, bsh, offset);
430 
431 	while (count--)
432 		*d++ = *addr++;
433 	__asm __volatile("eieio; sync");
434 }
435 
436 #if 0
437 #define	bus_space_write_region_stream_8	!!! unimplemented !!!
438 #endif
439 
440 /*
441  *	void bus_space_set_multi_N __P((bus_space_tag_t tag,
442  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
443  *	    size_t count));
444  *
445  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
446  * by tag/handle/offset `count' times.
447  */
448 
449 static __inline void
450 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
451     bus_size_t offset, u_int8_t val, size_t count)
452 {
453 	volatile u_int8_t *d = __BA(tag, bsh, offset);
454 
455 	while (count--)
456 		*d = val;
457 	__asm __volatile("eieio; sync");
458 }
459 
460 static __inline void
461 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
462     bus_size_t offset, u_int16_t val, size_t count)
463 {
464 	volatile u_int16_t *d = __BA(tag, bsh, offset);
465 
466 	while (count--)
467 		__asm __volatile("sthbrx %0, 0, %1" ::
468 			"r"(val), "r"(d));
469 	__asm __volatile("eieio; sync");
470 }
471 
472 static __inline void
473 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
474     bus_size_t offset, u_int32_t val, size_t count)
475 {
476 	volatile u_int32_t *d = __BA(tag, bsh, offset);
477 
478 	while (count--)
479 		__asm __volatile("stwbrx %0, 0, %1" ::
480 			"r"(val), "r"(d));
481 	__asm __volatile("eieio; sync");
482 }
483 
484 #if 0
485 #define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
486 #endif
487 
488 static __inline void
489 bus_space_set_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
490     bus_size_t offset, u_int16_t val, size_t count)
491 {
492 	volatile u_int16_t *d = __BA(tag, bsh, offset);
493 
494 	while (count--)
495 		*d = val;
496 	__asm __volatile("eieio; sync");
497 }
498 
499 static __inline void
500 bus_space_set_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
501     bus_size_t offset, u_int32_t val, size_t count)
502 {
503 	volatile u_int32_t *d = __BA(tag, bsh, offset);
504 
505 	while (count--)
506 		*d = val;
507 	__asm __volatile("eieio; sync");
508 }
509 
510 #if 0
511 #define	bus_space_set_multi_stream_8	!!! unimplemented !!!
512 #endif
513 
514 /*
515  *	void bus_space_set_region_N __P((bus_space_tag_t tag,
516  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
517  *	    size_t count));
518  *
519  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
520  * by tag/handle starting at `offset'.
521  */
522 
523 static __inline void
524 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
525     bus_size_t offset, u_int8_t val, size_t count)
526 {
527 	volatile u_int8_t *d = __BA(tag, bsh, offset);
528 
529 	while (count--)
530 		*d++ = val;
531 	__asm __volatile("eieio; sync");
532 }
533 
534 static __inline void
535 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
536     bus_size_t offset, u_int16_t val, size_t count)
537 {
538 	volatile u_int16_t *d = __BA(tag, bsh, offset);
539 
540 	while (count--)
541 		__asm __volatile("sthbrx %0, 0, %1" ::
542 			"r"(val), "r"(d++));
543 	__asm __volatile("eieio; sync");
544 }
545 
546 static __inline void
547 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
548     bus_size_t offset, u_int32_t val, size_t count)
549 {
550 	volatile u_int32_t *d = __BA(tag, bsh, offset);
551 
552 	while (count--)
553 		__asm __volatile("stwbrx %0, 0, %1" ::
554 			"r"(val), "r"(d++));
555 	__asm __volatile("eieio; sync");
556 }
557 
558 #if 0
559 #define	bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
560 #endif
561 
562 static __inline void
563 bus_space_set_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
564     bus_size_t offset, u_int16_t val, size_t count)
565 {
566 	volatile u_int16_t *d = __BA(tag, bsh, offset);
567 
568 	while (count--)
569 		*d++ = val;
570 	__asm __volatile("eieio; sync");
571 }
572 
573 static __inline void
574 bus_space_set_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
575     bus_size_t offset, u_int32_t val, size_t count)
576 {
577 	volatile u_int32_t *d = __BA(tag, bsh, offset);
578 
579 	while (count--)
580 		*d++ = val;
581 	__asm __volatile("eieio; sync");
582 }
583 
584 #if 0
585 #define	bus_space_set_region_stream_8	!!! unimplemented !!!
586 #endif
587 
588 /*
589  *	void bus_space_copy_region_N __P((bus_space_tag_t tag,
590  *	    bus_space_handle_t bsh1, bus_size_t off1,
591  *	    bus_space_handle_t bsh2, bus_size_t off2,
592  *	    size_t count));
593  *
594  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
595  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
596  */
597 
598 	/* XXX IMPLEMENT bus_space_copy_N() XXX */
599 
600 /*
601  * Bus read/write barrier methods.
602  *
603  *	void bus_space_barrier __P((bus_space_tag_t tag,
604  *	    bus_space_handle_t bsh, bus_size_t offset,
605  *	    bus_size_t len, int flags));
606  *
607  * Note: the macppc does not currently require barriers, but we must
608  * provide the flags to MI code.
609  */
610 
611 #define bus_space_barrier(t, h, o, l, f)	\
612 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
613 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
614 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
615 
616 #define	BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
617 
618 /*
619  * Bus DMA methods.
620  */
621 
622 /*
623  * Flags used in various bus DMA methods.
624  */
625 #define	BUS_DMA_WAITOK		0x00	/* safe to sleep (pseudo-flag) */
626 #define	BUS_DMA_NOWAIT		0x01	/* not safe to sleep */
627 #define	BUS_DMA_ALLOCNOW	0x02	/* perform resource allocation now */
628 #define	BUS_DMA_COHERENT	0x04	/* hint: map memory DMA coherent */
629 #define	BUS_DMA_BUS1		0x10	/* placeholders for bus functions... */
630 #define	BUS_DMA_BUS2		0x20
631 #define	BUS_DMA_BUS3		0x40
632 #define	BUS_DMA_BUS4		0x80
633 
634 /* Forwards needed by prototypes below. */
635 struct mbuf;
636 struct uio;
637 
638 /*
639  * Operations performed by bus_dmamap_sync().
640  */
641 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
642 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
643 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
644 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
645 
646 typedef struct macppc_bus_dma_tag	*bus_dma_tag_t;
647 typedef struct macppc_bus_dmamap	*bus_dmamap_t;
648 
649 /*
650  *	bus_dma_segment_t
651  *
652  *	Describes a single contiguous DMA transaction.  Values
653  *	are suitable for programming into DMA registers.
654  */
655 struct macppc_bus_dma_segment {
656 	bus_addr_t	ds_addr;	/* DMA address */
657 	bus_size_t	ds_len;		/* length of transfer */
658 };
659 typedef struct macppc_bus_dma_segment	bus_dma_segment_t;
660 
661 /*
662  *	bus_dma_tag_t
663  *
664  *	A machine-dependent opaque type describing the implementation of
665  *	DMA for a given bus.
666  */
667 
668 struct macppc_bus_dma_tag {
669 	/*
670 	 * The `bounce threshold' is checked while we are loading
671 	 * the DMA map.  If the physical address of the segment
672 	 * exceeds the threshold, an error will be returned.  The
673 	 * caller can then take whatever action is necessary to
674 	 * bounce the transfer.  If this value is 0, it will be
675 	 * ignored.
676 	 */
677 	bus_addr_t _bounce_thresh;
678 
679 	/*
680 	 * DMA mapping methods.
681 	 */
682 	int	(*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
683 		    bus_size_t, bus_size_t, int, bus_dmamap_t *));
684 	void	(*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
685 	int	(*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
686 		    bus_size_t, struct proc *, int));
687 	int	(*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
688 		    struct mbuf *, int));
689 	int	(*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
690 		    struct uio *, int));
691 	int	(*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
692 		    bus_dma_segment_t *, int, bus_size_t, int));
693 	void	(*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
694 	void	(*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
695 		    bus_addr_t, bus_size_t, int));
696 
697 	/*
698 	 * DMA memory utility functions.
699 	 */
700 	int	(*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
701 		    bus_size_t, bus_dma_segment_t *, int, int *, int));
702 	void	(*_dmamem_free) __P((bus_dma_tag_t,
703 		    bus_dma_segment_t *, int));
704 	int	(*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
705 		    int, size_t, caddr_t *, int));
706 	void	(*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
707 	vm_offset_t	(*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
708 		    int, off_t, int, int));
709 };
710 
711 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
712 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
713 #define	bus_dmamap_destroy(t, p)				\
714 	(*(t)->_dmamap_destroy)((t), (p))
715 #define	bus_dmamap_load(t, m, b, s, p, f)			\
716 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
717 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
718 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
719 #define	bus_dmamap_load_uio(t, m, u, f)				\
720 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
721 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
722 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
723 #define	bus_dmamap_unload(t, p)					\
724 	(*(t)->_dmamap_unload)((t), (p))
725 #define	bus_dmamap_sync(t, p, o, l, ops)			\
726 	(void)((t)->_dmamap_sync ?				\
727 	    (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
728 
729 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
730 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
731 #define	bus_dmamem_free(t, sg, n)				\
732 	(*(t)->_dmamem_free)((t), (sg), (n))
733 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
734 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
735 #define	bus_dmamem_unmap(t, k, s)				\
736 	(*(t)->_dmamem_unmap)((t), (k), (s))
737 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
738 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
739 
740 /*
741  *	bus_dmamap_t
742  *
743  *	Describes a DMA mapping.
744  */
745 struct macppc_bus_dmamap {
746 	/*
747 	 * PRIVATE MEMBERS: not for use my machine-independent code.
748 	 */
749 	bus_size_t	 _dm_size;	/* largest DMA transfer mappable */
750 	int		 _dm_segcnt;	/* number of segs this map can map */
751 	bus_size_t	 _dm_maxsegsz;	/* largest possible segment */
752 	bus_size_t	 _dm_boundary;	/* don't cross this */
753 	bus_addr_t	 _dm_bounce_thresh; /* bounce threshold; see tag */
754 	int		 _dm_flags;	/* misc. flags */
755 
756 	void		*_dm_cookie;	/* cookie for bus-specific functions */
757 
758 	/*
759 	 * PUBLIC MEMBERS: these are used by machine-independent code.
760 	 */
761 	bus_size_t	dm_mapsize;	/* size of the mapping */
762 	int		dm_nsegs;	/* # valid segments in mapping */
763 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
764 };
765 
766 #ifdef _MACPPC_BUS_DMA_PRIVATE
767 int	_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
768 	    bus_size_t, int, bus_dmamap_t *));
769 void	_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
770 int	_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
771 	    bus_size_t, struct proc *, int));
772 int	_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
773 	    struct mbuf *, int));
774 int	_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
775 	    struct uio *, int));
776 int	_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
777 	    bus_dma_segment_t *, int, bus_size_t, int));
778 void	_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
779 void	_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
780 	    bus_size_t, int));
781 
782 int	_bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
783 	    bus_size_t alignment, bus_size_t boundary,
784 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
785 void	_bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
786 	    int nsegs));
787 int	_bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
788 	    int nsegs, size_t size, caddr_t *kvap, int flags));
789 void	_bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
790 	    size_t size));
791 vm_offset_t	_bus_dmamem_mmap __P((bus_dma_tag_t tag,
792 	    bus_dma_segment_t *segs,
793 	    int nsegs, off_t off, int prot, int flags));
794 
795 int	_bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
796 	    bus_size_t alignment, bus_size_t boundary,
797 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
798 	    vm_offset_t low, vm_offset_t high));
799 
800 #endif /* _MACPPC_BUS_DMA_PRIVATE */
801 
802 #endif /* _MACPPC_BUS_H_ */
803