xref: /freebsd/sys/powerpc/include/bus.h (revision f9218d3d4fd34f082473b3a021c6d4d109fb47cf)
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       0xFFFFFFFF
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 1
91 
92 /*
93  * Values for the ppc bus space tag, not to be used directly by MI code.
94  * Low byte contains the shift value
95  */
96 #define PPC_BUS_SPACE_MEM      0x100       /* space is mem space */
97 #define PPC_BUS_MEM_MASK       0x0ff
98 
99 /*
100  * Flags for bus_resource_alloc(MEM|IOPORT). XXX this is very bad: it's
101  * assumed that this won't conflict with resource flags :-(
102  */
103 #define PPC_BUS_SPARSE4  0x800000  /* shift offset left 4 bits */
104 
105 /*
106  * Bus address and size types
107  */
108 typedef u_int32_t bus_addr_t;
109 typedef u_int32_t bus_size_t;
110 
111 /*
112  * Access methods for bus resources and address space.
113  */
114 typedef u_int32_t bus_space_tag_t;
115 typedef u_int32_t bus_space_handle_t;
116 
117 static __inline void *
118 __ppc_ba(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset)
119 {
120 	return ((void *)(handle + (offset << (tag & PPC_BUS_MEM_MASK))));
121 }
122 
123 
124 /*
125  *	int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
126  *	    bus_size_t size, int flags, bus_space_handle_t *bshp));
127  *
128  * Map a region of bus space.
129  */
130 #if 0
131 bus_space_map(t, addr, size, flags, bshp) ! not implemented !
132 #endif
133 
134 /*
135  *	int bus_space_unmap(bus_space_tag_t t,
136  *	    bus_space_handle_t bsh, bus_size_t size));
137  *
138  * Unmap a region of bus space.
139  */
140 
141 #define bus_space_unmap(t, bsh, size)
142 
143 /*
144  *	int bus_space_subregion(bus_space_tag_t t,
145  *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
146  *	    bus_space_handle_t *nbshp));
147  *
148  * Get a new handle for a subregion of an already-mapped area of bus space.
149  */
150 
151 #define	bus_space_subregion(t, bsh, offset, size, bshp)	\
152 	((*(bshp) = (bus_space_handle_t)__ppc_ba(	\
153 	    (t & ~PPC_BUS_MEM_MASK), bsh, offset)), 0)
154 /*
155  *	int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
156  *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
157  *	    bus_size_t boundary, int flags, bus_addr_t *addrp,
158  *	    bus_space_handle_t *bshp));
159  *
160  * Allocate a region of bus space.
161  */
162 
163 #if 0
164 #define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)	!!! unimplemented !!!
165 #endif
166 
167 /*
168  *	int bus_space_free(bus_space_tag_t t,
169  *	    bus_space_handle_t bsh, bus_size_t size));
170  *
171  * Free a region of bus space.
172  */
173 #if 0
174 #define	bus_space_free(t, h, s)		!!! unimplemented !!!
175 #endif
176 
177 /*
178  *	u_intN_t bus_space_read_N(bus_space_tag_t tag,
179  *	    bus_space_handle_t bsh, bus_size_t offset));
180  *
181  * Read a 1, 2, 4, or 8 byte quantity from bus space
182  * described by tag/handle/offset.
183  */
184 
185 #define	bus_space_read_1(t, h, o)	(in8(__ppc_ba(t, h, o)))
186 #define	bus_space_read_2(t, h, o)	(in16rb(__ppc_ba(t, h, o)))
187 #define	bus_space_read_4(t, h, o)	(in32rb(__ppc_ba(t, h, o)))
188 #if 0	/* Cause a link error for bus_space_read_8 */
189 #define	bus_space_read_8(t, h, o)	!!! unimplemented !!!
190 #endif
191 
192 #define	bus_space_read_stream_1(t, h, o)	(in8(__ppc_ba(t, h, o)))
193 #define	bus_space_read_stream_2(t, h, o)	(in16(__ppc_ba(t, h, o)))
194 #define	bus_space_read_stream_4(t, h, o)	(in32(__ppc_ba(t, h, o)))
195 #if 0	/* Cause a link error for bus_space_read_stream_8 */
196 #define	bus_space_read_stream_8(t, h, o)	!!! unimplemented !!!
197 #endif
198 
199 /*
200  *	void bus_space_read_multi_N(bus_space_tag_t tag,
201  *	    bus_space_handle_t bsh, bus_size_t offset,
202  *	    u_intN_t *addr, size_t count));
203  *
204  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
205  * described by tag/handle/offset and copy into buffer provided.
206  */
207 
208 #define	bus_space_read_multi_1(t, h, o, a, c) do {			\
209 		ins8(__ppc_ba(t, h, o), (a), (c));		       	\
210 	} while (0)
211 
212 #define	bus_space_read_multi_2(t, h, o, a, c) do {			\
213 		ins16rb(__ppc_ba(t, h, o), (a), (c));			\
214 	} while (0)
215 
216 #define	bus_space_read_multi_4(t, h, o, a, c) do {			\
217 		ins32rb(__ppc_ba(t, h, o), (a), (c));			\
218 	} while (0)
219 
220 #if 0	/* Cause a link error for bus_space_read_multi_8 */
221 #define	bus_space_read_multi_8		!!! unimplemented !!!
222 #endif
223 
224 #define	bus_space_read_multi_stream_1(t, h, o, a, c) do {		\
225 		ins8(__ppc_ba(t, h, o), (a), (c));		       	\
226 	} while (0)
227 
228 #define	bus_space_read_multi_stream_2(t, h, o, a, c) do {		\
229 		ins16(__ppc_ba(t, h, o), (a), (c));		       	\
230 	} while (0)
231 
232 #define	bus_space_read_multi_stream_4(t, h, o, a, c) do {		\
233 		ins32(__ppc_ba(t, h, o), (a), (c));		       	\
234 	} while (0)
235 
236 #if 0	/* Cause a link error for bus_space_read_multi_stream_8 */
237 #define	bus_space_read_multi_stream_8	!!! unimplemented !!!
238 #endif
239 
240 /*
241  *	void bus_space_read_region_N(bus_space_tag_t tag,
242  *	    bus_space_handle_t bsh, bus_size_t offset,
243  *	    u_intN_t *addr, size_t count));
244  *
245  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
246  * described by tag/handle and starting at `offset' and copy into
247  * buffer provided.
248  */
249 
250 static __inline void
251 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
252     bus_size_t offset, u_int8_t *addr, size_t count)
253 {
254 	volatile u_int8_t *s = __ppc_ba(tag, bsh, offset);
255 
256 	while (count--)
257 		*addr++ = *s++;
258 	__asm __volatile("eieio; sync");
259 }
260 
261 static __inline void
262 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
263     bus_size_t offset, u_int16_t *addr, size_t count)
264 {
265 	volatile u_int16_t *s = __ppc_ba(tag, bsh, offset);
266 
267 	while (count--)
268 		__asm __volatile("lhbrx %0, 0, %1" :
269 			"=r"(*addr++) : "r"(s++));
270 	__asm __volatile("eieio; sync");
271 }
272 
273 static __inline void
274 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
275     bus_size_t offset, u_int32_t *addr, size_t count)
276 {
277 	volatile u_int32_t *s = __ppc_ba(tag, bsh, offset);
278 
279 	while (count--)
280 		__asm __volatile("lwbrx %0, 0, %1" :
281 			"=r"(*addr++) : "r"(s++));
282 	__asm __volatile("eieio; sync");
283 }
284 
285 #if 0	/* Cause a link error for bus_space_read_region_8 */
286 #define	bus_space_read_region_8		!!! unimplemented !!!
287 #endif
288 
289 static __inline void
290 bus_space_read_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
291     bus_size_t offset, u_int16_t *addr, size_t count)
292 {
293 	volatile u_int16_t *s = __ppc_ba(tag, bsh, offset);
294 
295 	while (count--)
296 		*addr++ = *s++;
297 	__asm __volatile("eieio; sync");
298 }
299 
300 static __inline void
301 bus_space_read_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
302     bus_size_t offset, u_int32_t *addr, size_t count)
303 {
304 	volatile u_int32_t *s = __ppc_ba(tag, bsh, offset);
305 
306 	while (count--)
307 		*addr++ = *s++;
308 	__asm __volatile("eieio; sync");
309 }
310 
311 #if 0	/* Cause a link error */
312 #define	bus_space_read_region_stream_8		!!! unimplemented !!!
313 #endif
314 
315 /*
316  *	void bus_space_write_N(bus_space_tag_t tag,
317  *	    bus_space_handle_t bsh, bus_size_t offset,
318  *	    u_intN_t value));
319  *
320  * Write the 1, 2, 4, or 8 byte value `value' to bus space
321  * described by tag/handle/offset.
322  */
323 
324 #define bus_space_write_1(t, h, o, v)	out8(__ppc_ba(t, h, o), (v))
325 #define bus_space_write_2(t, h, o, v)	out16rb(__ppc_ba(t, h, o), (v))
326 #define bus_space_write_4(t, h, o, v)	out32rb(__ppc_ba(t, h, o), (v))
327 
328 #define bus_space_write_stream_1(t, h, o, v)	out8(__ppc_ba(t, h, o), (v))
329 #define bus_space_write_stream_2(t, h, o, v)	out16(__ppc_ba(t, h, o), (v))
330 #define bus_space_write_stream_4(t, h, o, v)	out32(__ppc_ba(t, h, o), (v))
331 
332 #if 0	/* Cause a link error for bus_space_write_8 */
333 #define bus_space_write_8		!!! unimplemented !!!
334 #endif
335 
336 /*
337  *	void bus_space_write_multi_N(bus_space_tag_t tag,
338  *	    bus_space_handle_t bsh, bus_size_t offset,
339  *	    const u_intN_t *addr, size_t count));
340  *
341  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
342  * provided to bus space described by tag/handle/offset.
343  */
344 
345 #define bus_space_write_multi_1(t, h, o, a, c) do {			\
346 		outsb(__ppc_ba(t, h, o), (a), (c));		       	\
347 	} while (0)
348 
349 #define bus_space_write_multi_2(t, h, o, a, c) do {			\
350 		outsw(__ppc_ba(t, h, o), (a), (c));		       	\
351 	} while (0)
352 
353 #define bus_space_write_multi_4(t, h, o, a, c) do {			\
354 		outsl(__ppc_ba(t, h, o), (a), (c));		       	\
355 	} while (0)
356 
357 #if 0
358 #define bus_space_write_multi_8		!!! unimplemented !!!
359 #endif
360 
361 #define bus_space_write_multi_stream_2(t, h, o, a, c) do {		\
362 		outsw(__ppc_ba(t, h, o), (a), (c));		       	\
363 	} while (0)
364 
365 #define bus_space_write_multi_stream_4(t, h, o, a, c) do {		\
366 		outsl(__ppc_ba(t, h, o), (a), (c));		       	\
367 	} while (0)
368 
369 #if 0
370 #define bus_space_write_multi_stream_8	!!! unimplemented !!!
371 #endif
372 
373 /*
374  *	void bus_space_write_region_N(bus_space_tag_t tag,
375  *	    bus_space_handle_t bsh, bus_size_t offset,
376  *	    const u_intN_t *addr, size_t count));
377  *
378  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
379  * to bus space described by tag/handle starting at `offset'.
380  */
381 
382 static __inline void
383 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
384     bus_size_t offset, const u_int8_t *addr, size_t count)
385 {
386 	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
387 
388 	while (count--)
389 		*d++ = *addr++;
390 	__asm __volatile("eieio; sync");
391 }
392 
393 static __inline void
394 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
395     bus_size_t offset, const u_int16_t *addr, size_t count)
396 {
397 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
398 
399 	while (count--)
400 		__asm __volatile("sthbrx %0, 0, %1" ::
401 			"r"(*addr++), "r"(d++));
402 	__asm __volatile("eieio; sync");
403 }
404 
405 static __inline void
406 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
407     bus_size_t offset, const u_int32_t *addr, size_t count)
408 {
409 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
410 
411 	while (count--)
412 		__asm __volatile("stwbrx %0, 0, %1" ::
413 			"r"(*addr++), "r"(d++));
414 	__asm __volatile("eieio; sync");
415 }
416 
417 #if 0
418 #define	bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!!
419 #endif
420 
421 static __inline void
422 bus_space_write_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
423     bus_size_t offset, const u_int16_t *addr, size_t count)
424 {
425 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
426 
427 	while (count--)
428 		*d++ = *addr++;
429 	__asm __volatile("eieio; sync");
430 }
431 
432 static __inline void
433 bus_space_write_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
434     bus_size_t offset, const u_int32_t *addr, size_t count)
435 {
436 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
437 
438 	while (count--)
439 		*d++ = *addr++;
440 	__asm __volatile("eieio; sync");
441 }
442 
443 #if 0
444 #define	bus_space_write_region_stream_8	!!! unimplemented !!!
445 #endif
446 
447 /*
448  *	void bus_space_set_multi_N(bus_space_tag_t tag,
449  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
450  *	    size_t count));
451  *
452  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
453  * by tag/handle/offset `count' times.
454  */
455 
456 static __inline void
457 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
458     bus_size_t offset, u_int8_t val, size_t count)
459 {
460 	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
461 
462 	while (count--)
463 		*d = val;
464 	__asm __volatile("eieio; sync");
465 }
466 
467 static __inline void
468 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
469     bus_size_t offset, u_int16_t val, size_t count)
470 {
471 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
472 
473 	while (count--)
474 		__asm __volatile("sthbrx %0, 0, %1" ::
475 			"r"(val), "r"(d));
476 	__asm __volatile("eieio; sync");
477 }
478 
479 static __inline void
480 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
481     bus_size_t offset, u_int32_t val, size_t count)
482 {
483 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
484 
485 	while (count--)
486 		__asm __volatile("stwbrx %0, 0, %1" ::
487 			"r"(val), "r"(d));
488 	__asm __volatile("eieio; sync");
489 }
490 
491 #if 0
492 #define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
493 #endif
494 
495 static __inline void
496 bus_space_set_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
497     bus_size_t offset, u_int16_t val, size_t count)
498 {
499 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
500 
501 	while (count--)
502 		*d = val;
503 	__asm __volatile("eieio; sync");
504 }
505 
506 static __inline void
507 bus_space_set_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
508     bus_size_t offset, u_int32_t val, size_t count)
509 {
510 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
511 
512 	while (count--)
513 		*d = val;
514 	__asm __volatile("eieio; sync");
515 }
516 
517 #if 0
518 #define	bus_space_set_multi_stream_8	!!! unimplemented !!!
519 #endif
520 
521 /*
522  *	void bus_space_set_region_N(bus_space_tag_t tag,
523  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
524  *	    size_t count));
525  *
526  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
527  * by tag/handle starting at `offset'.
528  */
529 
530 static __inline void
531 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
532     bus_size_t offset, u_int8_t val, size_t count)
533 {
534 	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
535 
536 	while (count--)
537 		*d++ = val;
538 	__asm __volatile("eieio; sync");
539 }
540 
541 static __inline void
542 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
543     bus_size_t offset, u_int16_t val, size_t count)
544 {
545 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
546 
547 	while (count--)
548 		__asm __volatile("sthbrx %0, 0, %1" ::
549 			"r"(val), "r"(d++));
550 	__asm __volatile("eieio; sync");
551 }
552 
553 static __inline void
554 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
555     bus_size_t offset, u_int32_t val, size_t count)
556 {
557 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
558 
559 	while (count--)
560 		__asm __volatile("stwbrx %0, 0, %1" ::
561 			"r"(val), "r"(d++));
562 	__asm __volatile("eieio; sync");
563 }
564 
565 #if 0
566 #define	bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
567 #endif
568 
569 static __inline void
570 bus_space_set_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
571     bus_size_t offset, u_int16_t val, size_t count)
572 {
573 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
574 
575 	while (count--)
576 		*d++ = val;
577 	__asm __volatile("eieio; sync");
578 }
579 
580 static __inline void
581 bus_space_set_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
582     bus_size_t offset, u_int32_t val, size_t count)
583 {
584 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
585 
586 	while (count--)
587 		*d++ = val;
588 	__asm __volatile("eieio; sync");
589 }
590 
591 #if 0
592 #define	bus_space_set_region_stream_8	!!! unimplemented !!!
593 #endif
594 
595 /*
596  *	void bus_space_copy_region_N(bus_space_tag_t tag,
597  *	    bus_space_handle_t bsh1, bus_size_t off1,
598  *	    bus_space_handle_t bsh2, bus_size_t off2,
599  *	    size_t count));
600  *
601  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
602  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
603  */
604 
605 	/* XXX IMPLEMENT bus_space_copy_N() XXX */
606 
607 /*
608  * Bus read/write barrier methods.
609  *
610  *	void bus_space_barrier(bus_space_tag_t tag,
611  *	    bus_space_handle_t bsh, bus_size_t offset,
612  *	    bus_size_t len, int flags));
613  *
614  * Note: the macppc does not currently require barriers, but we must
615  * provide the flags to MI code.
616  */
617 
618 #define bus_space_barrier(t, h, o, l, f)	\
619 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
620 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
621 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
622 
623 #define	BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
624 
625 /*
626  * Bus DMA methods.
627  */
628 
629 /*
630  * Flags used in various bus DMA methods.
631  */
632 #define	BUS_DMA_WAITOK		0x00	/* safe to sleep (pseudo-flag) */
633 #define	BUS_DMA_NOWAIT		0x01	/* not safe to sleep */
634 #define	BUS_DMA_ALLOCNOW	0x02	/* perform resource allocation now */
635 #define	BUS_DMA_COHERENT	0x04	/* hint: map memory DMA coherent */
636 #define	BUS_DMA_BUS1		0x10	/* placeholders for bus functions... */
637 #define	BUS_DMA_BUS2		0x20
638 #define	BUS_DMA_BUS3		0x40
639 #define	BUS_DMA_BUS4		0x80
640 
641 /* Forwards needed by prototypes below. */
642 struct mbuf;
643 struct uio;
644 
645 /*
646  *      bus_dmasync_op_t
647  *
648  *      Operations performed by bus_dmamap_sync().
649  */
650 typedef enum {
651 	BUS_DMASYNC_PREREAD,
652 	BUS_DMASYNC_POSTREAD,
653 	BUS_DMASYNC_PREWRITE,
654 	BUS_DMASYNC_POSTWRITE
655 } bus_dmasync_op_t;
656 
657 /*
658  *      bus_dma_tag_t
659  *
660  *      A machine-dependent opaque type describing the characteristics
661  *      of how to perform DMA mappings.  This structure encapsultes
662  *      information concerning address and alignment restrictions, number
663  *      of S/G  segments, amount of data per S/G segment, etc.
664  */
665 typedef struct bus_dma_tag	*bus_dma_tag_t;
666 
667 /*
668  *      bus_dmamap_t
669  *
670  *      DMA mapping instance information.
671  */
672 typedef struct bus_dmamap	*bus_dmamap_t;
673 
674 /*
675  *	bus_dma_segment_t
676  *
677  *	Describes a single contiguous DMA transaction.  Values
678  *	are suitable for programming into DMA registers.
679  */
680 typedef struct bus_dma_segment {
681 	bus_addr_t	ds_addr;	/* DMA address */
682 	bus_size_t	ds_len;		/* length of transfer */
683 } bus_dma_segment_t;
684 
685 /*
686  * A function that returns 1 if the address cannot be accessed by
687  * a device and 0 if it can be.
688  */
689 typedef int bus_dma_filter_t(void *, bus_addr_t);
690 
691 /*
692  * Allocate a device specific dma_tag encapsulating the constraints of
693  * the parent tag in addition to other restrictions specified:
694  *
695  *      alignment:      alignment for segments.
696  *      boundary:       Boundary that segments cannot cross.
697  *      lowaddr:        Low restricted address that cannot appear in a mapping.
698  *      highaddr:       High restricted address that cannot appear in a mapping.
699  *      filtfunc:       An optional function to further test if an address
700  *                      within the range of lowaddr and highaddr cannot appear
701  *                      in a mapping.
702  *      filtfuncarg:    An argument that will be passed to filtfunc in addition
703  *                      to the address to test.
704  *      maxsize:        Maximum mapping size supported by this tag.
705  *      nsegments:      Number of discontinuities allowed in maps.
706  *      maxsegsz:       Maximum size of a segment in the map.
707  *      flags:          Bus DMA flags.
708  *      dmat:           A pointer to set to a valid dma tag should the return
709  *                      value of this function indicate success.
710  */
711 int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment,
712 		       bus_size_t boundary, bus_addr_t lowaddr,
713 		       bus_addr_t highaddr, bus_dma_filter_t *filtfunc,
714 		       void *filtfuncarg, bus_size_t maxsize, int nsegments,
715 		       bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat);
716 
717 int bus_dma_tag_destroy(bus_dma_tag_t dmat);
718 
719 /*
720  * Allocate a handle for mapping from kva/uva/physical
721  * address space into bus device space.
722  */
723 int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp);
724 
725 /*
726  * Destroy  a handle for mapping from kva/uva/physical
727  * address space into bus device space.
728  */
729 int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map);
730 
731 /*
732  * Allocate a piece of memory that can be efficiently mapped into
733  * bus device space based on the constraints lited in the dma tag.
734  * A dmamap to for use with dmamap_load is also allocated.
735  */
736 int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
737 		     bus_dmamap_t *mapp);
738 
739 /*
740  * Free a piece of memory and it's allociated dmamap, that was allocated
741  * via bus_dmamem_alloc.
742  */
743 void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map);
744 
745 /*
746  * A function that processes a successfully loaded dma map or an error
747  * from a delayed load map.
748  */
749 typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
750 
751 /*
752  * Map the buffer buf into bus space using the dmamap map.
753  */
754 int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
755 		    bus_size_t buflen, bus_dmamap_callback_t *callback,
756 		    void *callback_arg, int flags);
757 
758 /*
759  * Like bus_dmamap_callback but includes map size in bytes.  This is
760  * defined as a separate interface to maintain compatiiblity for users
761  * of bus_dmamap_callback_t--at some point these interfaces should be merged.
762  */
763 typedef void bus_dmamap_callback2_t(void *, bus_dma_segment_t *, int, bus_size_t, int);
764 /*
765  * Like bus_dmamap_load but for mbufs.  Note the use of the
766  * bus_dmamap_callback2_t interface.
767  */
768 int bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map,
769 			 struct mbuf *mbuf,
770 			 bus_dmamap_callback2_t *callback, void *callback_arg,
771 			 int flags);
772 /*
773  * Like bus_dmamap_load but for uios.  Note the use of the
774  * bus_dmamap_callback2_t interface.
775  */
776 int bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map,
777 			struct uio *ui,
778 			bus_dmamap_callback2_t *callback, void *callback_arg,
779 			int flags);
780 
781 /*
782  * Perform a syncronization operation on the given map.
783  */
784 void bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t);
785 
786 /*
787  * Release the mapping held by map.
788  */
789 void bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map);
790 
791 #endif /* _MACPPC_BUS_H_ */
792