xref: /netbsd/sys/arch/luna68k/include/bus.h (revision bf9ec67e)
1 /*	$NetBSD: bus.h,v 1.4 2001/08/25 23:08:39 chs 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 _MACHINE_BUS_H_
67 #define _MACHINE_BUS_H_
68 
69 /*
70  * Value for the luna68k bus space tag, not to be used directly by MI code.
71  */
72 #define MACHINE_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  *	u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
146  *	    bus_space_handle_t bsh, bus_size_t offset));
147  *
148  * Read a 1, 2, 4, or 8 byte quantity from bus space
149  * described by tag/handle/offset.
150  */
151 
152 #define	bus_space_read_1(t, h, o)					\
153     ((void) t, (*(volatile u_int8_t *)((h) + 4*(o))))
154 
155 #define	bus_space_read_2(t, h, o)					\
156     ((void) t, (*(volatile u_int16_t *)((h) + 4*(o))))
157 
158 #define	bus_space_read_4(t, h, o)					\
159     ((void) t, (*(volatile u_int32_t *)((h) + 4*(o))))
160 
161 #if 0	/* Cause a link error for bus_space_read_8 */
162 #define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
163 #endif
164 
165 /*
166  *	void bus_space_read_multi_N __P((bus_space_tag_t tag,
167  *	    bus_space_handle_t bsh, bus_size_t offset,
168  *	    u_intN_t *addr, size_t count));
169  *
170  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
171  * described by tag/handle/offset and copy into buffer provided.
172  */
173 
174 #define	bus_space_read_multi_1(t, h, o, a, c) do {			\
175 	(void) t;							\
176 	__asm __volatile ("						\
177 		movl	%0,%%a0					;	\
178 		movl	%1,%%a1					;	\
179 		movl	%2,%%d0					;	\
180 	1:	movb	%%a0@,%%a1@+				;	\
181 		subql	#1,%%d0					;	\
182 		jne	1b"					:	\
183 								:	\
184 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
185 		    "a0","a1","d0");					\
186 } while (0)
187 
188 #define	bus_space_read_multi_2(t, h, o, a, c) do {			\
189 	(void) t;							\
190 	__asm __volatile ("						\
191 		movl	%0,%%a0					;	\
192 		movl	%1,%%a1					;	\
193 		movl	%2,%%d0					;	\
194 	1:	movw	%%a0@,%%a1@+				;	\
195 		subql	#1,%%d0					;	\
196 		jne	1b"					:	\
197 								:	\
198 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
199 		    "a0","a1","d0");					\
200 } while (0)
201 
202 #define	bus_space_read_multi_4(t, h, o, a, c) do {			\
203 	(void) t;							\
204 	__asm __volatile ("						\
205 		movl	%0,%%a0					;	\
206 		movl	%1,%%a1					;	\
207 		movl	%2,%%d0					;	\
208 	1:	movl	%%a0@,%%a1@+				;	\
209 		subql	#1,%%d0					;	\
210 		jne	1b"					:	\
211 								:	\
212 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
213 		    "a0","a1","d0");					\
214 } while (0)
215 
216 #if 0	/* Cause a link error for bus_space_read_multi_8 */
217 #define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
218 #endif
219 
220 /*
221  *	void bus_space_read_region_N __P((bus_space_tag_t tag,
222  *	    bus_space_handle_t bsh, bus_size_t offset,
223  *	    u_intN_t *addr, size_t count));
224  *
225  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
226  * described by tag/handle and starting at `offset' and copy into
227  * buffer provided.
228  */
229 
230 #define	bus_space_read_region_1(t, h, o, a, c) do {			\
231 	(void) t;							\
232 	__asm __volatile ("						\
233 		movl	%0,%%a0					;	\
234 		movl	%1,%%a1					;	\
235 		movl	%2,%%d0					;	\
236 	1:	movb	%%a0@+,%%a1@+				;	\
237 		subql	#1,%%d0					;	\
238 		jne	1b"					:	\
239 								:	\
240 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
241 		    "a0","a1","d0");					\
242 } while (0)
243 
244 #define	bus_space_read_region_2(t, h, o, a, c) do {			\
245 	(void) t;							\
246 	__asm __volatile ("						\
247 		movl	%0,%%a0					;	\
248 		movl	%1,%%a1					;	\
249 		movl	%2,%%d0					;	\
250 	1:	movw	%%a0@+,%%a1@+				;	\
251 		subql	#1,%%d0					;	\
252 		jne	1b"					:	\
253 								:	\
254 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
255 		    "a0","a1","d0");					\
256 } while (0)
257 
258 #define	bus_space_read_region_4(t, h, o, a, c) do {			\
259 	(void) t;							\
260 	__asm __volatile ("						\
261 		movl	%0,%%a0					;	\
262 		movl	%1,%%a1					;	\
263 		movl	%2,%%d0					;	\
264 	1:	movl	%%a0@+,%%a1@+				;	\
265 		subql	#1,%%d0					;	\
266 		jne	1b"					:	\
267 								:	\
268 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
269 		    "a0","a1","d0");					\
270 } while (0)
271 
272 #if 0	/* Cause a link error for bus_space_read_region_8 */
273 #define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
274 #endif
275 
276 /*
277  *	void bus_space_write_N __P((bus_space_tag_t tag,
278  *	    bus_space_handle_t bsh, bus_size_t offset,
279  *	    u_intN_t value));
280  *
281  * Write the 1, 2, 4, or 8 byte value `value' to bus space
282  * described by tag/handle/offset.
283  */
284 
285 #define	bus_space_write_1(t, h, o, v)					\
286     ((void) t, ((void)(*(volatile u_int8_t *)((h) + 4*(o)) = (v))))
287 
288 #define	bus_space_write_2(t, h, o, v)					\
289     ((void) t, ((void)(*(volatile u_int16_t *)((h) + 4*(o)) = (v))))
290 
291 #define	bus_space_write_4(t, h, o, v)					\
292     ((void) t, ((void)(*(volatile u_int32_t *)((h) + 4*(o)) = (v))))
293 
294 #if 0	/* Cause a link error for bus_space_write_8 */
295 #define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
296 #endif
297 
298 /*
299  *	void bus_space_write_multi_N __P((bus_space_tag_t tag,
300  *	    bus_space_handle_t bsh, bus_size_t offset,
301  *	    const u_intN_t *addr, size_t count));
302  *
303  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
304  * provided to bus space described by tag/handle/offset.
305  */
306 
307 #define	bus_space_write_multi_1(t, h, o, a, c) do {			\
308 	(void) t;							\
309 	__asm __volatile ("						\
310 		movl	%0,%%a0					;	\
311 		movl	%1,%%a1					;	\
312 		movl	%2,%%d0					;	\
313 	1:	movb	a1@+,%%a0@				;	\
314 		subql	#1,%%d0					;	\
315 		jne	1b"					:	\
316 								:	\
317 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
318 		    "a0","a1","d0");					\
319 } while (0)
320 
321 #define	bus_space_write_multi_2(t, h, o, a, c) do {			\
322 	(void) t;							\
323 	__asm __volatile ("						\
324 		movl	%0,%%a0					;	\
325 		movl	%1,%%a1					;	\
326 		movl	%2,%%d0					;	\
327 	1:	movw	a1@+,%%a0@				;	\
328 		subql	#1,%%d0					;	\
329 		jne	1b"					:	\
330 								:	\
331 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
332 		    "a0","a1","d0");					\
333 } while (0)
334 
335 #define	bus_space_write_multi_4(t, h, o, a, c) do {			\
336 	(void) t;							\
337 	__asm __volatile ("						\
338 		movl	%0,%%a0					;	\
339 		movl	%1,%%a1					;	\
340 		movl	%2,%%d0					;	\
341 	1:	movl	a1@+,%%a0@				;	\
342 		subql	#1,%%d0					;	\
343 		jne	1b"					:	\
344 								:	\
345 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
346 		    "a0","a1","d0");					\
347 } while (0)
348 
349 #if 0	/* Cause a link error for bus_space_write_8 */
350 #define	bus_space_write_multi_8(t, h, o, a, c)				\
351 			!!! bus_space_write_multi_8 unimplimented !!!
352 #endif
353 
354 /*
355  *	void bus_space_write_region_N __P((bus_space_tag_t tag,
356  *	    bus_space_handle_t bsh, bus_size_t offset,
357  *	    const u_intN_t *addr, size_t count));
358  *
359  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
360  * to bus space described by tag/handle starting at `offset'.
361  */
362 
363 #define	bus_space_write_region_1(t, h, o, a, c) do {			\
364 	(void) t;							\
365 	__asm __volatile ("						\
366 		movl	%0,%%a0					;	\
367 		movl	%1,%%a1					;	\
368 		movl	%2,%%d0					;	\
369 	1:	movb	a1@+,%%a0@+				;	\
370 		subql	#1,%%d0					;	\
371 		jne	1b"					:	\
372 								:	\
373 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
374 		    "a0","a1","d0");					\
375 } while (0)
376 
377 #define	bus_space_write_region_2(t, h, o, a, c) do {			\
378 	(void) t;							\
379 	__asm __volatile ("						\
380 		movl	%0,%%a0					;	\
381 		movl	%1,%%a1					;	\
382 		movl	%2,%%d0					;	\
383 	1:	movw	a1@+,%%a0@+				;	\
384 		subql	#1,%%d0					;	\
385 		jne	1b"					:	\
386 								:	\
387 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
388 		    "a0","a1","d0");					\
389 } while (0)
390 
391 #define	bus_space_write_region_4(t, h, o, a, c) do {			\
392 	(void) t;							\
393 	__asm __volatile ("						\
394 		movl	%0,%%a0					;	\
395 		movl	%1,%%a1					;	\
396 		movl	%2,%%d0					;	\
397 	1:	movl	a1@+,%%a0@+				;	\
398 		subql	#1,%%d0					;	\
399 		jne	1b"					:	\
400 								:	\
401 		    "r" ((h) + (o)), "g" (a), "g" ((size_t)(c))	:	\
402 		    "a0","a1","d0");					\
403 } while (0)
404 
405 #if 0	/* Cause a link error for bus_space_write_region_8 */
406 #define	bus_space_write_region_8					\
407 			!!! bus_space_write_region_8 unimplemented !!!
408 #endif
409 
410 /*
411  *	void bus_space_set_multi_N __P((bus_space_tag_t tag,
412  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
413  *	    size_t count));
414  *
415  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
416  * by tag/handle/offset `count' times.
417  */
418 
419 #define	bus_space_set_multi_1(t, h, o, val, c) do {			\
420 	(void) t;							\
421 	__asm __volatile ("						\
422 		movl	%0,%%a0					;	\
423 		movl	%1,%%d1					;	\
424 		movl	%2,%%d0					;	\
425 	1:	movb	%%d1,%%a0@				;	\
426 		subql	#1,%%d0					;	\
427 		jne	1b"					:	\
428 								:	\
429 		    "r" ((h)+(o)), "g" ((u_long)val),			\
430 					 "g" ((size_t)(c))	:	\
431 		    "a0","d0","d1");					\
432 } while (0)
433 
434 #define	bus_space_set_multi_2(t, h, o, val, c) do {			\
435 	(void) t;							\
436 	__asm __volatile ("						\
437 		movl	%0,%%a0					;	\
438 		movl	%1,%%d1					;	\
439 		movl	%2,%%d0					;	\
440 	1:	movw	%%d1,%%a0@				;	\
441 		subql	#1,%%d0					;	\
442 		jne	1b"					:	\
443 								:	\
444 		    "r" ((h)+(o)), "g" ((u_long)val),			\
445 					 "g" ((size_t)(c))	:	\
446 		    "a0","d0","d1");					\
447 } while (0)
448 
449 #define	bus_space_set_multi_4(t, h, o, val, c) do {			\
450 	(void) t;							\
451 	__asm __volatile ("						\
452 		movl	%0,%%a0					;	\
453 		movl	%1,%%d1					;	\
454 		movl	%2,%%d0					;	\
455 	1:	movl	%%d1,%%a0@				;	\
456 		subql	#1,%%d0					;	\
457 		jne	1b"					:	\
458 								:	\
459 		    "r" ((h)+(o)), "g" ((u_long)val),			\
460 					 "g" ((size_t)(c))	:	\
461 		    "a0","d0","d1");					\
462 } while (0)
463 
464 #if 0	/* Cause a link error for bus_space_set_multi_8 */
465 #define	bus_space_set_multi_8						\
466 			!!! bus_space_set_multi_8 unimplemented !!!
467 #endif
468 
469 /*
470  *	void bus_space_set_region_N __P((bus_space_tag_t tag,
471  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
472  *	    size_t count));
473  *
474  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
475  * by tag/handle starting at `offset'.
476  */
477 
478 #define	bus_space_set_region_1(t, h, o, val, c) do {			\
479 	(void) t;							\
480 	__asm __volatile ("						\
481 		movl	%0,%%a0					;	\
482 		movl	%1,%%d1					;	\
483 		movl	%2,%%d0					;	\
484 	1:	movb	%%d1,%%a0@+				;	\
485 		subql	#1,%%d0					;	\
486 		jne	1b"					:	\
487 								:	\
488 		    "r" ((h)+(o)), "g" ((u_long)val),			\
489 					"g" ((size_t)(c))	:	\
490 		    "a0","d0","d1");					\
491 } while (0)
492 
493 #define	bus_space_set_region_2(t, h, o, val, c) do {			\
494 	(void) t;							\
495 	__asm __volatile ("						\
496 		movl	%0,%%a0					;	\
497 		movl	%1,%%d1					;	\
498 		movl	%2,%%d0					;	\
499 	1:	movw	%%d1,%%a0@+				;	\
500 		subql	#1,%%d0					;	\
501 		jne	1b"					:	\
502 								:	\
503 		    "r" ((h)+(o)), "g" ((u_long)val),			\
504 					"g" ((size_t)(c))	:	\
505 		    "a0","d0","d1");					\
506 } while (0)
507 
508 #define	bus_space_set_region_4(t, h, o, val, c) do {			\
509 	(void) t;							\
510 	__asm __volatile ("						\
511 		movl	%0,%%a0					;	\
512 		movl	%1,%%d1					;	\
513 		movl	%2,%%d0					;	\
514 	1:	movl	%%d1,%%a0@+				;	\
515 		subql	#1,%%d0					;	\
516 		jne	1b"					:	\
517 								:	\
518 		    "r" ((h)+(o)), "g" ((u_long)val),			\
519 					"g" ((size_t)(c))	:	\
520 		    "a0","d0","d1");					\
521 } while (0)
522 
523 #if 0	/* Cause a link error for bus_space_set_region_8 */
524 #define	bus_space_set_region_8						\
525 			!!! bus_space_set_region_8 unimplemented !!!
526 #endif
527 
528 /*
529  *	void bus_space_copy_N __P((bus_space_tag_t tag,
530  *	    bus_space_handle_t bsh1, bus_size_t off1,
531  *	    bus_space_handle_t bsh2, bus_size_t off2,
532  *	    size_t count));
533  *
534  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
535  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
536  */
537 
538 #define	__MACHINE_copy_region_N(BYTES)					\
539 static __inline void __CONCAT(bus_space_copy_region_,BYTES)		\
540 	__P((bus_space_tag_t,						\
541 	    bus_space_handle_t bsh1, bus_size_t off1,			\
542 	    bus_space_handle_t bsh2, bus_size_t off2,			\
543 	    bus_size_t count));						\
544 									\
545 static __inline void							\
546 __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c)		\
547 	bus_space_tag_t t;						\
548 	bus_space_handle_t h1, h2;					\
549 	bus_size_t o1, o2, c;						\
550 {									\
551 	bus_size_t o;							\
552 									\
553 	if ((h1 + o1) >= (h2 + o2)) {					\
554 		/* src after dest: copy forward */			\
555 		for (o = 0; c != 0; c--, o += BYTES)			\
556 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
557 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
558 	} else {							\
559 		/* dest after src: copy backwards */			\
560 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
561 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
562 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
563 	}								\
564 }
565 __MACHINE_copy_region_N(1)
566 __MACHINE_copy_region_N(2)
567 __MACHINE_copy_region_N(4)
568 #if 0	/* Cause a link error for bus_space_copy_8 */
569 #define	bus_space_copy_8						\
570 			!!! bus_space_copy_8 unimplemented !!!
571 #endif
572 
573 #undef __MACHINE_copy_region_N
574 
575 /*
576  * Bus read/write barrier methods.
577  *
578  *	void bus_space_barrier __P((bus_space_tag_t tag,
579  *	    bus_space_handle_t bsh, bus_size_t offset,
580  *	    bus_size_t len, int flags));
581  *
582  * Note: the 680x0 does not currently require barriers, but we must
583  * provide the flags to MI code.
584  */
585 #define	bus_space_barrier(t, h, o, l, f)	\
586 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
587 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
588 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
589 
590 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
591 
592 #endif /* _MACHINE_BUS_H_ */
593