xref: /freebsd/sys/powerpc/include/bus.h (revision d056fa046c6a91b90cd98165face0e42a33a5173)
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/_bus.h>
76 #include <machine/pio.h>
77 
78 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
79 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
80 #define BUS_SPACE_MAXSIZE       0xFFFFFFFF
81 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
82 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
83 #define BUS_SPACE_MAXADDR       0xFFFFFFFF
84 
85 #define BUS_SPACE_UNRESTRICTED  (~0)
86 
87 /*
88  * Values for the macppc bus space tag, not to be used directly by MI code.
89  */
90 
91 #define	__BUS_SPACE_HAS_STREAM_METHODS 1
92 
93 /*
94  * Define the PPC tag values
95  */
96 #define PPC_BUS_SPACE_MEM	1	/* space is mem space */
97 #define PPC_BUS_SPACE_IO	2	/* space is io space */
98 
99 static __inline void *
100 __ppc_ba(bus_space_tag_t tag __unused, bus_space_handle_t handle,
101     bus_size_t offset)
102 {
103 	return ((void *)(handle + offset));
104 }
105 
106 /*
107  *	int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
108  *	    bus_size_t size, int flags, bus_space_handle_t *bshp));
109  *
110  * Map a region of bus space.
111  */
112 
113 static __inline int
114 bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
115 	      bus_size_t size __unused, int flags __unused,
116 	      bus_space_handle_t *bshp)
117 {
118 
119 	return (ENXIO);
120 }
121 
122 /*
123  *	int bus_space_unmap(bus_space_tag_t t,
124  *	    bus_space_handle_t bsh, bus_size_t size));
125  *
126  * Unmap a region of bus space.
127  */
128 
129 static __inline void
130 bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
131                 bus_size_t size __unused)
132 {
133 }
134 
135 /*
136  *	int bus_space_subregion(bus_space_tag_t t,
137  *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
138  *	    bus_space_handle_t *nbshp));
139  *
140  * Get a new handle for a subregion of an already-mapped area of bus space.
141  */
142 
143 static __inline int
144 bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
145     bus_size_t offset, bus_size_t size __unused, bus_space_handle_t *nbshp)
146 {
147 	*nbshp = bsh + offset;
148 	return (0);
149 }
150 
151 /*
152  *	int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
153  *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
154  *	    bus_size_t boundary, int flags, bus_addr_t *addrp,
155  *	    bus_space_handle_t *bshp));
156  *
157  * Allocate a region of bus space.
158  */
159 
160 #if 0
161 #define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)	!!! unimplemented !!!
162 #endif
163 
164 /*
165  *	int bus_space_free(bus_space_tag_t t,
166  *	    bus_space_handle_t bsh, bus_size_t size));
167  *
168  * Free a region of bus space.
169  */
170 #if 0
171 #define	bus_space_free(t, h, s)		!!! unimplemented !!!
172 #endif
173 
174 /*
175  *	u_intN_t bus_space_read_N(bus_space_tag_t tag,
176  *	    bus_space_handle_t bsh, bus_size_t offset));
177  *
178  * Read a 1, 2, 4, or 8 byte quantity from bus space
179  * described by tag/handle/offset.
180  */
181 
182 static __inline u_int8_t
183 bus_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
184 {
185 	return (in8(__ppc_ba(t, h, o)));
186 }
187 
188 static __inline u_int16_t
189 bus_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
190 {
191 	return (in16rb(__ppc_ba(t, h, o)));
192 }
193 
194 static __inline u_int32_t
195 bus_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
196 {
197 	return (in32rb(__ppc_ba(t, h, o)));
198 }
199 
200 #if 0	/* Cause a link error for bus_space_read_8 */
201 #define	bus_space_read_8(t, h, o)	!!! unimplemented !!!
202 #endif
203 
204 static __inline u_int8_t
205 bus_space_read_stream_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
206 {
207 	return (in8(__ppc_ba(t, h, o)));
208 }
209 
210 static __inline u_int16_t
211 bus_space_read_stream_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
212 {
213 	return (in16(__ppc_ba(t, h, o)));
214 }
215 
216 static __inline u_int32_t
217 bus_space_read_stream_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
218 {
219 	return (in32(__ppc_ba(t, h, o)));
220 }
221 
222 #if 0	/* Cause a link error for bus_space_read_stream_8 */
223 #define	bus_space_read_stream_8(t, h, o)	!!! unimplemented !!!
224 #endif
225 
226 /*
227  *	void bus_space_read_multi_N(bus_space_tag_t tag,
228  *	    bus_space_handle_t bsh, bus_size_t offset,
229  *	    u_intN_t *addr, size_t count));
230  *
231  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
232  * described by tag/handle/offset and copy into buffer provided.
233  */
234 
235 static __inline void
236 bus_space_read_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
237     u_int8_t *a, size_t c)
238 {
239 	ins8(__ppc_ba(t, h, o), a, c);
240 }
241 
242 static __inline void
243 bus_space_read_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
244     u_int16_t *a, size_t c)
245 {
246 	ins16rb(__ppc_ba(t, h, o), a, c);
247 }
248 
249 static __inline void
250 bus_space_read_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
251     u_int32_t *a, size_t c)
252 {
253 	ins32rb(__ppc_ba(t, h, o), a, c);
254 }
255 
256 #if 0	/* Cause a link error for bus_space_read_multi_8 */
257 #define	bus_space_read_multi_8		!!! unimplemented !!!
258 #endif
259 
260 static __inline void
261 bus_space_read_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
262     bus_size_t o, u_int8_t *a, size_t c)
263 {
264 	ins8(__ppc_ba(t, h, o), a, c);
265 }
266 
267 static __inline void
268 bus_space_read_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
269     bus_size_t o, u_int16_t *a, size_t c)
270 {
271 	ins16(__ppc_ba(t, h, o), a, c);
272 }
273 
274 static __inline void
275 bus_space_read_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
276     bus_size_t o, u_int32_t *a, size_t c)
277 {
278 	ins32(__ppc_ba(t, h, o), a, c);
279 }
280 
281 #if 0	/* Cause a link error for bus_space_read_multi_stream_8 */
282 #define	bus_space_read_multi_stream_8	!!! unimplemented !!!
283 #endif
284 
285 /*
286  *	void bus_space_read_region_N(bus_space_tag_t tag,
287  *	    bus_space_handle_t bsh, bus_size_t offset,
288  *	    u_intN_t *addr, size_t count));
289  *
290  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
291  * described by tag/handle and starting at `offset' and copy into
292  * buffer provided.
293  */
294 
295 static __inline void
296 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
297     bus_size_t offset, u_int8_t *addr, size_t count)
298 {
299 	volatile u_int8_t *s = __ppc_ba(tag, bsh, offset);
300 
301 	while (count--)
302 		*addr++ = *s++;
303 	__asm __volatile("eieio; sync");
304 }
305 
306 static __inline void
307 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
308     bus_size_t offset, u_int16_t *addr, size_t count)
309 {
310 	volatile u_int16_t *s = __ppc_ba(tag, bsh, offset);
311 
312 	while (count--)
313 		__asm __volatile("lhbrx %0, 0, %1" :
314 			"=r"(*addr++) : "r"(s++));
315 	__asm __volatile("eieio; sync");
316 }
317 
318 static __inline void
319 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
320     bus_size_t offset, u_int32_t *addr, size_t count)
321 {
322 	volatile u_int32_t *s = __ppc_ba(tag, bsh, offset);
323 
324 	while (count--)
325 		__asm __volatile("lwbrx %0, 0, %1" :
326 			"=r"(*addr++) : "r"(s++));
327 	__asm __volatile("eieio; sync");
328 }
329 
330 #if 0	/* Cause a link error for bus_space_read_region_8 */
331 #define	bus_space_read_region_8		!!! unimplemented !!!
332 #endif
333 
334 static __inline void
335 bus_space_read_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
336     bus_size_t offset, u_int16_t *addr, size_t count)
337 {
338 	volatile u_int16_t *s = __ppc_ba(tag, bsh, offset);
339 
340 	while (count--)
341 		*addr++ = *s++;
342 	__asm __volatile("eieio; sync");
343 }
344 
345 static __inline void
346 bus_space_read_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
347     bus_size_t offset, u_int32_t *addr, size_t count)
348 {
349 	volatile u_int32_t *s = __ppc_ba(tag, bsh, offset);
350 
351 	while (count--)
352 		*addr++ = *s++;
353 	__asm __volatile("eieio; sync");
354 }
355 
356 #if 0	/* Cause a link error */
357 #define	bus_space_read_region_stream_8		!!! unimplemented !!!
358 #endif
359 
360 /*
361  *	void bus_space_write_N(bus_space_tag_t tag,
362  *	    bus_space_handle_t bsh, bus_size_t offset,
363  *	    u_intN_t value));
364  *
365  * Write the 1, 2, 4, or 8 byte value `value' to bus space
366  * described by tag/handle/offset.
367  */
368 
369 static __inline void
370 bus_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
371     uint8_t v)
372 {
373 	out8(__ppc_ba(t, h, o), v);
374 }
375 
376 static __inline void
377 bus_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
378     uint16_t v)
379 {
380 	out16rb(__ppc_ba(t, h, o), v);
381 }
382 
383 static __inline void
384 bus_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
385     uint32_t v)
386 {
387 	out32rb(__ppc_ba(t, h, o), v);
388 }
389 
390 #if 0	/* Cause a link error for bus_space_write_8 */
391 #define bus_space_write_8		!!! unimplemented !!!
392 #endif
393 
394 static __inline void
395 bus_space_write_stream_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
396     uint8_t v)
397 {
398 	out8(__ppc_ba(t, h, o), v);
399 }
400 
401 static __inline void
402 bus_space_write_stream_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
403     uint16_t v)
404 {
405 	out16(__ppc_ba(t, h, o), v);
406 }
407 
408 static __inline void
409 bus_space_write_stream_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
410     uint32_t v)
411 {
412 	out32(__ppc_ba(t, h, o), v);
413 }
414 
415 #if 0	/* Cause a link error for bus_space_write_stream_8 */
416 #define bus_space_write_stream_8       	!!! unimplemented !!!
417 #endif
418 
419 
420 /*
421  *	void bus_space_write_multi_N(bus_space_tag_t tag,
422  *	    bus_space_handle_t bsh, bus_size_t offset,
423  *	    const u_intN_t *addr, size_t count));
424  *
425  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
426  * provided to bus space described by tag/handle/offset.
427  */
428 
429 static __inline void
430 bus_space_write_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
431     uint8_t *a, size_t c)
432 {
433 	outsb(__ppc_ba(t, h, o), a, c);
434 }
435 
436 static __inline void
437 bus_space_write_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
438     uint16_t *a, size_t c)
439 {
440 	outsw(__ppc_ba(t, h, o), a, c);
441 }
442 
443 static __inline void
444 bus_space_write_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
445     uint32_t *a, size_t c)
446 {
447 	outsl(__ppc_ba(t, h, o), a, c);
448 }
449 
450 #if 0
451 #define bus_space_write_multi_8		!!! unimplemented !!!
452 #endif
453 
454 static __inline void
455 bus_space_write_multi_stream_1(bus_space_tag_t t, bus_space_handle_t h,
456     bus_size_t o, const u_int8_t *a, size_t c)
457 {
458 	outsb(__ppc_ba(t, h, o), a, c);
459 }
460 
461 static __inline void
462 bus_space_write_multi_stream_2(bus_space_tag_t t, bus_space_handle_t h,
463     bus_size_t o, const u_int16_t *a, size_t c)
464 {
465 	outsw(__ppc_ba(t, h, o), a, c);
466 }
467 
468 static __inline void
469 bus_space_write_multi_stream_4(bus_space_tag_t t, bus_space_handle_t h,
470     bus_size_t o, const u_int32_t *a, size_t c)
471 {
472 	outsl(__ppc_ba(t, h, o), a, c);
473 }
474 
475 #if 0
476 #define bus_space_write_multi_stream_8	!!! unimplemented !!!
477 #endif
478 
479 /*
480  *	void bus_space_write_region_N(bus_space_tag_t tag,
481  *	    bus_space_handle_t bsh, bus_size_t offset,
482  *	    const u_intN_t *addr, size_t count));
483  *
484  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
485  * to bus space described by tag/handle starting at `offset'.
486  */
487 
488 static __inline void
489 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
490     bus_size_t offset, const u_int8_t *addr, size_t count)
491 {
492 	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
493 
494 	while (count--)
495 		*d++ = *addr++;
496 	__asm __volatile("eieio; sync");
497 }
498 
499 static __inline void
500 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
501     bus_size_t offset, const u_int16_t *addr, size_t count)
502 {
503 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
504 
505 	while (count--)
506 		__asm __volatile("sthbrx %0, 0, %1" ::
507 			"r"(*addr++), "r"(d++));
508 	__asm __volatile("eieio; sync");
509 }
510 
511 static __inline void
512 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
513     bus_size_t offset, const u_int32_t *addr, size_t count)
514 {
515 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
516 
517 	while (count--)
518 		__asm __volatile("stwbrx %0, 0, %1" ::
519 			"r"(*addr++), "r"(d++));
520 	__asm __volatile("eieio; sync");
521 }
522 
523 #if 0
524 #define	bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!!
525 #endif
526 
527 static __inline void
528 bus_space_write_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
529     bus_size_t offset, const u_int16_t *addr, size_t count)
530 {
531 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
532 
533 	while (count--)
534 		*d++ = *addr++;
535 	__asm __volatile("eieio; sync");
536 }
537 
538 static __inline void
539 bus_space_write_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
540     bus_size_t offset, const u_int32_t *addr, size_t count)
541 {
542 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
543 
544 	while (count--)
545 		*d++ = *addr++;
546 	__asm __volatile("eieio; sync");
547 }
548 
549 #if 0
550 #define	bus_space_write_region_stream_8	!!! unimplemented !!!
551 #endif
552 
553 /*
554  *	void bus_space_set_multi_N(bus_space_tag_t tag,
555  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
556  *	    size_t count));
557  *
558  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
559  * by tag/handle/offset `count' times.
560  */
561 
562 static __inline void
563 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
564     bus_size_t offset, u_int8_t val, size_t count)
565 {
566 	volatile u_int8_t *d = __ppc_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_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
575     bus_size_t offset, u_int16_t val, size_t count)
576 {
577 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
578 
579 	while (count--)
580 		__asm __volatile("sthbrx %0, 0, %1" ::
581 			"r"(val), "r"(d));
582 	__asm __volatile("eieio; sync");
583 }
584 
585 static __inline void
586 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
587     bus_size_t offset, u_int32_t val, size_t count)
588 {
589 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
590 
591 	while (count--)
592 		__asm __volatile("stwbrx %0, 0, %1" ::
593 			"r"(val), "r"(d));
594 	__asm __volatile("eieio; sync");
595 }
596 
597 #if 0
598 #define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
599 #endif
600 
601 static __inline void
602 bus_space_set_multi_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
603     bus_size_t offset, u_int16_t val, size_t count)
604 {
605 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
606 
607 	while (count--)
608 		*d = val;
609 	__asm __volatile("eieio; sync");
610 }
611 
612 static __inline void
613 bus_space_set_multi_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
614     bus_size_t offset, u_int32_t val, size_t count)
615 {
616 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
617 
618 	while (count--)
619 		*d = val;
620 	__asm __volatile("eieio; sync");
621 }
622 
623 #if 0
624 #define	bus_space_set_multi_stream_8	!!! unimplemented !!!
625 #endif
626 
627 /*
628  *	void bus_space_set_region_N(bus_space_tag_t tag,
629  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
630  *	    size_t count));
631  *
632  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
633  * by tag/handle starting at `offset'.
634  */
635 
636 static __inline void
637 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
638     bus_size_t offset, u_int8_t val, size_t count)
639 {
640 	volatile u_int8_t *d = __ppc_ba(tag, bsh, offset);
641 
642 	while (count--)
643 		*d++ = val;
644 	__asm __volatile("eieio; sync");
645 }
646 
647 static __inline void
648 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
649     bus_size_t offset, u_int16_t val, size_t count)
650 {
651 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
652 
653 	while (count--)
654 		__asm __volatile("sthbrx %0, 0, %1" ::
655 			"r"(val), "r"(d++));
656 	__asm __volatile("eieio; sync");
657 }
658 
659 static __inline void
660 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
661     bus_size_t offset, u_int32_t val, size_t count)
662 {
663 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
664 
665 	while (count--)
666 		__asm __volatile("stwbrx %0, 0, %1" ::
667 			"r"(val), "r"(d++));
668 	__asm __volatile("eieio; sync");
669 }
670 
671 #if 0
672 #define	bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
673 #endif
674 
675 static __inline void
676 bus_space_set_region_stream_2(bus_space_tag_t tag, bus_space_handle_t bsh,
677     bus_size_t offset, u_int16_t val, size_t count)
678 {
679 	volatile u_int16_t *d = __ppc_ba(tag, bsh, offset);
680 
681 	while (count--)
682 		*d++ = val;
683 	__asm __volatile("eieio; sync");
684 }
685 
686 static __inline void
687 bus_space_set_region_stream_4(bus_space_tag_t tag, bus_space_handle_t bsh,
688     bus_size_t offset, u_int32_t val, size_t count)
689 {
690 	volatile u_int32_t *d = __ppc_ba(tag, bsh, offset);
691 
692 	while (count--)
693 		*d++ = val;
694 	__asm __volatile("eieio; sync");
695 }
696 
697 #if 0
698 #define	bus_space_set_region_stream_8	!!! unimplemented !!!
699 #endif
700 
701 /*
702  *	void bus_space_copy_region_N(bus_space_tag_t tag,
703  *	    bus_space_handle_t bsh1, bus_size_t off1,
704  *	    bus_space_handle_t bsh2, bus_size_t off2,
705  *	    size_t count));
706  *
707  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
708  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
709  */
710 
711 	/* XXX IMPLEMENT bus_space_copy_N() XXX */
712 
713 /*
714  * Bus read/write barrier methods.
715  *
716  *	void bus_space_barrier(bus_space_tag_t tag,
717  *	    bus_space_handle_t bsh, bus_size_t offset,
718  *	    bus_size_t len, int flags));
719  *
720  * Note: the macppc does not currently require barriers, but we must
721  * provide the flags to MI code.
722  */
723 
724 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
725 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
726 
727 static __inline void
728 bus_space_barrier(bus_space_tag_t tag __unused,
729     bus_space_handle_t bsh __unused, bus_size_t offset __unused,
730     bus_size_t len __unused, int flags __unused)
731 {
732 	__asm __volatile("" : : : "memory");
733 }
734 
735 
736 #define	BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
737 
738 #include <machine/bus_dma.h>
739 
740 #endif /* _MACPPC_BUS_H_ */
741