xref: /netbsd-src/sys/arch/mac68k/include/bus.h (revision 481fca6e59249d8ffcf24fef7cfbe7b131bfb080)
1 /*	$NetBSD: bus.h,v 1.13 2000/01/25 22:13:22 drochner Exp $	*/
2 
3 /*-
4  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9  * NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the NetBSD
22  *	Foundation, Inc. and its contributors.
23  * 4. Neither the name of The NetBSD Foundation nor the names of its
24  *    contributors may be used to endorse or promote products derived
25  *    from this software without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37  * POSSIBILITY OF SUCH DAMAGE.
38  */
39 
40 /*
41  * Copyright (C) 1997 Scott Reynolds.  All rights reserved.
42  *
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  * 1. Redistributions of source code must retain the above copyright
47  *    notice, this list of conditions and the following disclaimer.
48  * 2. Redistributions in binary form must reproduce the above copyright
49  *    notice, this list of conditions and the following disclaimer in the
50  *    documentation and/or other materials provided with the distribution.
51  * 3. The name of the author may not be used to endorse or promote products
52  *    derived from this software without specific prior written permission
53  *
54  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
55  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
56  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
57  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
58  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
59  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
60  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
61  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64  */
65 
66 #ifndef _MAC68K_BUS_H_
67 #define _MAC68K_BUS_H_
68 
69 /*
70  * Value for the mac68k bus space tag, not to be used directly by MI code.
71  */
72 #define MAC68K_BUS_SPACE_MEM	0	/* space is mem space */
73 
74 /*
75  * Bus address and size types
76  */
77 typedef u_long bus_addr_t;
78 typedef u_long bus_size_t;
79 
80 /*
81  * Access methods for bus resources and address space.
82  */
83 typedef int	bus_space_tag_t;
84 typedef u_long	bus_space_handle_t;
85 
86 /*
87  *	int bus_space_map __P((bus_space_tag_t t, bus_addr_t addr,
88  *	    bus_size_t size, int flags, bus_space_handle_t *bshp));
89  *
90  * Map a region of bus space.
91  */
92 
93 #define	BUS_SPACE_MAP_CACHEABLE		0x01
94 #define	BUS_SPACE_MAP_LINEAR		0x02
95 #define	BUS_SPACE_MAP_PREFETCHABLE	0x04
96 
97 int	bus_space_map __P((bus_space_tag_t, bus_addr_t, bus_size_t,
98 	    int, bus_space_handle_t *));
99 
100 /*
101  *	void bus_space_unmap __P((bus_space_tag_t t,
102  *	    bus_space_handle_t bsh, bus_size_t size));
103  *
104  * Unmap a region of bus space.
105  */
106 
107 void	bus_space_unmap __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
108 
109 /*
110  *	int bus_space_subregion __P((bus_space_tag_t t,
111  *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
112  *	    bus_space_handle_t *nbshp));
113  *
114  * Get a new handle for a subregion of an already-mapped area of bus space.
115  */
116 
117 int	bus_space_subregion __P((bus_space_tag_t t, bus_space_handle_t bsh,
118 	    bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp));
119 
120 /*
121  *	int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t, rstart,
122  *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
123  *	    bus_size_t boundary, int flags, bus_addr_t *addrp,
124  *	    bus_space_handle_t *bshp));
125  *
126  * Allocate a region of bus space.
127  */
128 
129 int	bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
130 	    bus_addr_t rend, bus_size_t size, bus_size_t align,
131 	    bus_size_t boundary, int cacheable, bus_addr_t *addrp,
132 	    bus_space_handle_t *bshp));
133 
134 /*
135  *	int bus_space_free __P((bus_space_tag_t t,
136  *	    bus_space_handle_t bsh, bus_size_t size));
137  *
138  * Free a region of bus space.
139  */
140 
141 void	bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
142 	    bus_size_t size));
143 
144 /*
145  *	int mac68k_bus_space_probe __P((bus_space_tag_t t,
146  *	    bus_space_handle_t bsh, bus_size_t offset, int sz));
147  *
148  * Probe the bus at t/bsh/offset, using sz as the size of the load.
149  *
150  * This is a machine-dependent extension, and is not to be used by
151  * machine-independent code.
152  */
153 
154 int	mac68k_bus_space_probe __P((bus_space_tag_t t,
155 	    bus_space_handle_t bsh, bus_size_t offset, int sz));
156 
157 /*
158  *	u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
159  *	    bus_space_handle_t bsh, bus_size_t offset));
160  *
161  * Read a 1, 2, 4, or 8 byte quantity from bus space
162  * described by tag/handle/offset.
163  */
164 
165 #define	bus_space_read_1(t, h, o)					\
166     ((void) t, (*(volatile u_int8_t *)((h) + (o))))
167 
168 #define	bus_space_read_2(t, h, o)					\
169     ((void) t, (*(volatile u_int16_t *)((h) + (o))))
170 
171 #define	bus_space_read_4(t, h, o)					\
172     ((void) t, (*(volatile u_int32_t *)((h) + (o))))
173 
174 #if 0	/* Cause a link error for bus_space_read_8 */
175 #define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
176 #endif
177 
178 /*
179  *	void bus_space_read_multi_N __P((bus_space_tag_t tag,
180  *	    bus_space_handle_t bsh, bus_size_t offset,
181  *	    u_intN_t *addr, size_t count));
182  *
183  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
184  * described by tag/handle/offset and copy into buffer provided.
185  */
186 
187 #define	bus_space_read_multi_1(t, h, o, a, c) do {			\
188 	(void) t;							\
189 	__asm __volatile ("						\
190 		movl	%0,a0					;	\
191 		movl	%1,a1					;	\
192 		movl	%2,d0					;	\
193 	1:	movb	a0@,a1@+				;	\
194 		subql	#1,d0					;	\
195 		jne	1b"					:	\
196 								:	\
197 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
198 		    "a0","a1","d0");					\
199 } while (0)
200 
201 #define	bus_space_read_multi_2(t, h, o, a, c) do {			\
202 	(void) t;							\
203 	__asm __volatile ("						\
204 		movl	%0,a0					;	\
205 		movl	%1,a1					;	\
206 		movl	%2,d0					;	\
207 	1:	movw	a0@,a1@+				;	\
208 		subql	#1,d0					;	\
209 		jne	1b"					:	\
210 								:	\
211 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
212 		    "a0","a1","d0");					\
213 } while (0)
214 
215 #define	bus_space_read_multi_4(t, h, o, a, c) do {			\
216 	(void) t;							\
217 	__asm __volatile ("						\
218 		movl	%0,a0					;	\
219 		movl	%1,a1					;	\
220 		movl	%2,d0					;	\
221 	1:	movl	a0@,a1@+				;	\
222 		subql	#1,d0					;	\
223 		jne	1b"					:	\
224 								:	\
225 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
226 		    "a0","a1","d0");					\
227 } while (0)
228 
229 #if 0	/* Cause a link error for bus_space_read_multi_8 */
230 #define	bus_space_read_multi_8	!!! bus_space_read_multi_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 #define	bus_space_read_region_1(t, h, o, a, c) do {			\
244 	(void) t;							\
245 	__asm __volatile ("						\
246 		movl	%0,a0					;	\
247 		movl	%1,a1					;	\
248 		movl	%2,d0					;	\
249 	1:	movb	a0@+,a1@+				;	\
250 		subql	#1,d0					;	\
251 		jne	1b"					:	\
252 								:	\
253 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
254 		    "a0","a1","d0");					\
255 } while (0)
256 
257 #define	bus_space_read_region_2(t, h, o, a, c) do {			\
258 	(void) t;							\
259 	__asm __volatile ("						\
260 		movl	%0,a0					;	\
261 		movl	%1,a1					;	\
262 		movl	%2,d0					;	\
263 	1:	movw	a0@+,a1@+				;	\
264 		subql	#1,d0					;	\
265 		jne	1b"					:	\
266 								:	\
267 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
268 		    "a0","a1","d0");					\
269 } while (0)
270 
271 #define	bus_space_read_region_4(t, h, o, a, c) do {			\
272 	(void) t;							\
273 	__asm __volatile ("						\
274 		movl	%0,a0					;	\
275 		movl	%1,a1					;	\
276 		movl	%2,d0					;	\
277 	1:	movl	a0@+,a1@+				;	\
278 		subql	#1,d0					;	\
279 		jne	1b"					:	\
280 								:	\
281 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
282 		    "a0","a1","d0");					\
283 } while (0)
284 
285 #if 0	/* Cause a link error for bus_space_read_region_8 */
286 #define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
287 #endif
288 
289 /*
290  *	void bus_space_write_N __P((bus_space_tag_t tag,
291  *	    bus_space_handle_t bsh, bus_size_t offset,
292  *	    u_intN_t value));
293  *
294  * Write the 1, 2, 4, or 8 byte value `value' to bus space
295  * described by tag/handle/offset.
296  */
297 
298 #define	bus_space_write_1(t, h, o, v)					\
299     ((void) t, ((void)(*(volatile u_int8_t *)((h) + (o)) = (v))))
300 
301 #define	bus_space_write_2(t, h, o, v)					\
302     ((void) t, ((void)(*(volatile u_int16_t *)((h) + (o)) = (v))))
303 
304 #define	bus_space_write_4(t, h, o, v)					\
305     ((void) t, ((void)(*(volatile u_int32_t *)((h) + (o)) = (v))))
306 
307 #if 0	/* Cause a link error for bus_space_write_8 */
308 #define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
309 #endif
310 
311 /*
312  *	void bus_space_write_multi_N __P((bus_space_tag_t tag,
313  *	    bus_space_handle_t bsh, bus_size_t offset,
314  *	    const u_intN_t *addr, size_t count));
315  *
316  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
317  * provided to bus space described by tag/handle/offset.
318  */
319 
320 #define	bus_space_write_multi_1(t, h, o, a, c) do {			\
321 	(void) t;							\
322 	__asm __volatile ("						\
323 		movl	%0,a0					;	\
324 		movl	%1,a1					;	\
325 		movl	%2,d0					;	\
326 	1:	movb	a1@+,a0@				;	\
327 		subql	#1,d0					;	\
328 		jne	1b"					:	\
329 								:	\
330 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
331 		    "a0","a1","d0");					\
332 } while (0)
333 
334 #define	bus_space_write_multi_2(t, h, o, a, c) do {			\
335 	(void) t;							\
336 	__asm __volatile ("						\
337 		movl	%0,a0					;	\
338 		movl	%1,a1					;	\
339 		movl	%2,d0					;	\
340 	1:	movw	a1@+,a0@				;	\
341 		subql	#1,d0					;	\
342 		jne	1b"					:	\
343 								:	\
344 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
345 		    "a0","a1","d0");					\
346 } while (0)
347 
348 #define	bus_space_write_multi_4(t, h, o, a, c) do {			\
349 	(void) t;							\
350 	__asm __volatile ("						\
351 		movl	%0,a0					;	\
352 		movl	%1,a1					;	\
353 		movl	%2,d0					;	\
354 	1:	movl	a1@+,a0@				;	\
355 		subql	#1,d0					;	\
356 		jne	1b"					:	\
357 								:	\
358 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
359 		    "a0","a1","d0");					\
360 } while (0)
361 
362 #if 0	/* Cause a link error for bus_space_write_8 */
363 #define	bus_space_write_multi_8(t, h, o, a, c)				\
364 			!!! bus_space_write_multi_8 unimplimented !!!
365 #endif
366 
367 /*
368  *	void bus_space_write_region_N __P((bus_space_tag_t tag,
369  *	    bus_space_handle_t bsh, bus_size_t offset,
370  *	    const u_intN_t *addr, size_t count));
371  *
372  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
373  * to bus space described by tag/handle starting at `offset'.
374  */
375 
376 #define	bus_space_write_region_1(t, h, o, a, c) do {			\
377 	(void) t;							\
378 	__asm __volatile ("						\
379 		movl	%0,a0					;	\
380 		movl	%1,a1					;	\
381 		movl	%2,d0					;	\
382 	1:	movb	a1@+,a0@+				;	\
383 		subql	#1,d0					;	\
384 		jne	1b"					:	\
385 								:	\
386 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
387 		    "a0","a1","d0");					\
388 } while (0)
389 
390 #define	bus_space_write_region_2(t, h, o, a, c) do {			\
391 	(void) t;							\
392 	__asm __volatile ("						\
393 		movl	%0,a0					;	\
394 		movl	%1,a1					;	\
395 		movl	%2,d0					;	\
396 	1:	movw	a1@+,a0@+				;	\
397 		subql	#1,d0					;	\
398 		jne	1b"					:	\
399 								:	\
400 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
401 		    "a0","a1","d0");					\
402 } while (0)
403 
404 #define	bus_space_write_region_4(t, h, o, a, c) do {			\
405 	(void) t;							\
406 	__asm __volatile ("						\
407 		movl	%0,a0					;	\
408 		movl	%1,a1					;	\
409 		movl	%2,d0					;	\
410 	1:	movl	a1@+,a0@+				;	\
411 		subql	#1,d0					;	\
412 		jne	1b"					:	\
413 								:	\
414 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
415 		    "a0","a1","d0");					\
416 } while (0)
417 
418 #if 0	/* Cause a link error for bus_space_write_region_8 */
419 #define	bus_space_write_region_8					\
420 			!!! bus_space_write_region_8 unimplemented !!!
421 #endif
422 
423 /*
424  *	void bus_space_set_multi_N __P((bus_space_tag_t tag,
425  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
426  *	    size_t count));
427  *
428  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
429  * by tag/handle/offset `count' times.
430  */
431 
432 #define	bus_space_set_multi_1(t, h, o, val, c) do {			\
433 	(void) t;							\
434 	__asm __volatile ("						\
435 		movl	%0,a0					;	\
436 		movl	%1,d1					;	\
437 		movl	%2,d0					;	\
438 	1:	movb	d1,a0@					;	\
439 		subql	#1,d0					;	\
440 		jne	1b"					:	\
441 								:	\
442 		    "r" ((h)+(o)), "g" ((u_long)val),			\
443 					 "g" ((size_t)(c))	:	\
444 		    "a0","d0","d1");					\
445 } while (0)
446 
447 #define	bus_space_set_multi_2(t, h, o, val, c) do {			\
448 	(void) t;							\
449 	__asm __volatile ("						\
450 		movl	%0,a0					;	\
451 		movl	%1,d1					;	\
452 		movl	%2,d0					;	\
453 	1:	movw	d1,a0@					;	\
454 		subql	#1,d0					;	\
455 		jne	1b"					:	\
456 								:	\
457 		    "r" ((h)+(o)), "g" ((u_long)val),			\
458 					 "g" ((size_t)(c))	:	\
459 		    "a0","d0","d1");					\
460 } while (0)
461 
462 #define	bus_space_set_multi_4(t, h, o, val, c) do {			\
463 	(void) t;							\
464 	__asm __volatile ("						\
465 		movl	%0,a0					;	\
466 		movl	%1,d1					;	\
467 		movl	%2,d0					;	\
468 	1:	movl	d1,a0@					;	\
469 		subql	#1,d0					;	\
470 		jne	1b"					:	\
471 								:	\
472 		    "r" ((h)+(o)), "g" ((u_long)val),			\
473 					 "g" ((size_t)(c))	:	\
474 		    "a0","d0","d1");					\
475 } while (0)
476 
477 #if 0	/* Cause a link error for bus_space_set_multi_8 */
478 #define	bus_space_set_multi_8						\
479 			!!! bus_space_set_multi_8 unimplemented !!!
480 #endif
481 
482 /*
483  *	void bus_space_set_region_N __P((bus_space_tag_t tag,
484  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
485  *	    size_t count));
486  *
487  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
488  * by tag/handle starting at `offset'.
489  */
490 
491 #define	bus_space_set_region_1(t, h, o, val, c) do {			\
492 	(void) t;							\
493 	__asm __volatile ("						\
494 		movl	%0,a0					;	\
495 		movl	%1,d1					;	\
496 		movl	%2,d0					;	\
497 	1:	movb	d1,a0@+					;	\
498 		subql	#1,d0					;	\
499 		jne	1b"					:	\
500 								:	\
501 		    "r" ((h)+(o)), "g" ((u_long)val),			\
502 					"g" ((size_t)(c))	:	\
503 		    "a0","d0","d1");					\
504 } while (0)
505 
506 #define	bus_space_set_region_2(t, h, o, val, c) do {			\
507 	(void) t;							\
508 	__asm __volatile ("						\
509 		movl	%0,a0					;	\
510 		movl	%1,d1					;	\
511 		movl	%2,d0					;	\
512 	1:	movw	d1,a0@+					;	\
513 		subql	#1,d0					;	\
514 		jne	1b"					:	\
515 								:	\
516 		    "r" ((h)+(o)), "g" ((u_long)val),			\
517 					"g" ((size_t)(c))	:	\
518 		    "a0","d0","d1");					\
519 } while (0)
520 
521 #define	bus_space_set_region_4(t, h, o, val, c) do {			\
522 	(void) t;							\
523 	__asm __volatile ("						\
524 		movl	%0,a0					;	\
525 		movl	%1,d1					;	\
526 		movl	%2,d0					;	\
527 	1:	movl	d1,a0@+					;	\
528 		subql	#1,d0					;	\
529 		jne	1b"					:	\
530 								:	\
531 		    "r" ((h)+(o)), "g" ((u_long)val),			\
532 					"g" ((size_t)(c))	:	\
533 		    "a0","d0","d1");					\
534 } while (0)
535 
536 #if 0	/* Cause a link error for bus_space_set_region_8 */
537 #define	bus_space_set_region_8						\
538 			!!! bus_space_set_region_8 unimplemented !!!
539 #endif
540 
541 /*
542  *	void bus_space_copy_N __P((bus_space_tag_t tag,
543  *	    bus_space_handle_t bsh1, bus_size_t off1,
544  *	    bus_space_handle_t bsh2, bus_size_t off2,
545  *	    size_t count));
546  *
547  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
548  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
549  */
550 
551 #define	__MAC68K_copy_region_N(BYTES)					\
552 static __inline void __CONCAT(bus_space_copy_region_,BYTES)		\
553 	__P((bus_space_tag_t,						\
554 	    bus_space_handle_t bsh1, bus_size_t off1,			\
555 	    bus_space_handle_t bsh2, bus_size_t off2,			\
556 	    bus_size_t count));						\
557 									\
558 static __inline void							\
559 __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c)		\
560 	bus_space_tag_t t;						\
561 	bus_space_handle_t h1, h2;					\
562 	bus_size_t o1, o2, c;						\
563 {									\
564 	bus_size_t o;							\
565 									\
566 	if ((h1 + o1) >= (h2 + o2)) {					\
567 		/* src after dest: copy forward */			\
568 		for (o = 0; c != 0; c--, o += BYTES)			\
569 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
570 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
571 	} else {							\
572 		/* dest after src: copy backwards */			\
573 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
574 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
575 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
576 	}								\
577 }
578 __MAC68K_copy_region_N(1)
579 __MAC68K_copy_region_N(2)
580 __MAC68K_copy_region_N(4)
581 #if 0	/* Cause a link error for bus_space_copy_8 */
582 #define	bus_space_copy_8						\
583 			!!! bus_space_copy_8 unimplemented !!!
584 #endif
585 
586 #undef __MAC68K_copy_region_N
587 
588 /*
589  * Bus read/write barrier methods.
590  *
591  *	void bus_space_barrier __P((bus_space_tag_t tag,
592  *	    bus_space_handle_t bsh, bus_size_t offset,
593  *	    bus_size_t len, int flags));
594  *
595  * Note: the 680x0 does not currently require barriers, but we must
596  * provide the flags to MI code.
597  */
598 #define	bus_space_barrier(t, h, o, l, f)	\
599 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
600 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
601 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
602 
603 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
604 
605 #endif /* _MAC68K_BUS_H_ */
606