xref: /netbsd-src/sys/arch/mvme68k/include/bus_space.h (revision a5847cc334d9a7029f6352b847e9e8d71a0f9e0c)
1 /*	$NetBSD: bus_space.h,v 1.13 2008/04/28 20:23:29 martin 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  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Copyright (C) 1997 Scott Reynolds.  All rights reserved.
35  *
36  * Redistribution and use in source and binary forms, with or without
37  * modification, are permitted provided that the following conditions
38  * are met:
39  * 1. Redistributions of source code must retain the above copyright
40  *    notice, this list of conditions and the following disclaimer.
41  * 2. Redistributions in binary form must reproduce the above copyright
42  *    notice, this list of conditions and the following disclaimer in the
43  *    documentation and/or other materials provided with the distribution.
44  * 3. The name of the author may not be used to endorse or promote products
45  *    derived from this software without specific prior written permission
46  *
47  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
48  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
51  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
52  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
53  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
54  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
55  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
56  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
57  */
58 
59 /*
60  * Lifted from the Next68k port.
61  * Modified for mvme68k by Steve Woodford.
62  *
63  * TODO: Support for VMEbus...
64  * (Do any existing VME card drivers use bus_space_* ?)
65  */
66 
67 #ifndef _MVME68K_BUS_SPACE_H_
68 #define	_MVME68K_BUS_SPACE_H_
69 
70 /*
71  * Addresses (in bus space).
72  */
73 typedef u_long bus_addr_t;
74 typedef u_long bus_size_t;
75 
76 /*
77  * Access methods for bus resources and address space.
78  */
79 struct mvme68k_bus_space_tag;
80 typedef struct mvme68k_bus_space_tag	*bus_space_tag_t;
81 typedef u_long	bus_space_handle_t;
82 
83 struct mvme68k_bus_space_tag {
84 	void		*bs_cookie;
85 	int		(*bs_map)(void *, bus_addr_t, bus_size_t,
86 				  int, bus_space_handle_t *);
87 	void		(*bs_unmap)(void *, bus_space_handle_t, bus_size_t);
88 	int		(*bs_peek_1)(void *, bus_space_handle_t,
89 				     bus_size_t, uint8_t *);
90 	int		(*bs_peek_2)(void *, bus_space_handle_t,
91 				     bus_size_t, uint16_t *);
92 	int		(*bs_peek_4)(void *, bus_space_handle_t,
93 				     bus_size_t, uint32_t *);
94 #if 0
95 	int		(*bs_peek_8)(void *, bus_space_handle_t,
96 				     bus_size_t, uint64_t *);
97 #endif
98 	int		(*bs_poke_1)(void *, bus_space_handle_t,
99 				     bus_size_t, uint8_t);
100 	int		(*bs_poke_2)(void *, bus_space_handle_t,
101 				     bus_size_t, uint16_t);
102 	int		(*bs_poke_4)(void *, bus_space_handle_t,
103 				     bus_size_t, uint32_t);
104 #if 0
105 	int		(*bs_poke_8)(void *, bus_space_handle_t,
106 				     bus_size_t, uint64_t);
107 #endif
108 };
109 
110 /*
111  *	int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
112  *	                  bus_size_t size, int flags,
113  *                        bus_space_handle_t *bshp);
114  *
115  * Map a region of bus space.
116  */
117 #define	bus_space_map(tag, offset, size, flags, handlep)		\
118     (*((tag)->bs_map))((tag)->bs_cookie, (offset), (size), (flags), (handlep))
119 
120 /*
121  * Possible values for the 'flags' parameter of bus_space_map()
122  */
123 #define	BUS_SPACE_MAP_CACHEABLE		0x01
124 #define	BUS_SPACE_MAP_LINEAR		0x02
125 #define	BUS_SPACE_MAP_PREFETCHABLE	0x04
126 
127 /*
128  *	void bus_space_unmap(bus_space_tag_t t,
129  *                           bus_space_handle_t bsh, bus_size_t size);
130  *
131  * Unmap a region of bus space.
132  */
133 #define bus_space_unmap(tag, handle, size)				\
134     (*((tag)->bs_unmap))((tag)->bs_cookie, (handle), (size))
135 
136 /*
137  *	int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h
138  *	    bus_addr_t offset, bus_size_t size, bus_space_handle_t *newh);
139  *
140  * Allocate a sub-region of an existing map
141  */
142 #define	bus_space_subregion(t, h, o, s, hp)				\
143      ((*(hp)=(h)+(o)), 0)
144 
145 /*
146  * Allocation and deallocation operations.
147  */
148 #define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)  		\
149      (-1)
150 
151 #define	bus_space_free(t, h, s)
152 
153 /*
154  *	int bus_space_peek_N(bus_space_tag_t tag,
155  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t *valuep);
156  *
157  * Cautiously read 1, 2, 4 or 8 byte quantity from bus space described
158  * by tag/handle/offset.
159  * If no hardware responds to the read access, the function returns a
160  * non-zero value. Otherwise the value read is placed in `valuep'.
161  */
162 #define	bus_space_peek_1(t, h, o, vp)					\
163     (*((t)->bs_peek_1))((t)->bs_cookie, (h), (o), (vp))
164 
165 #define	bus_space_peek_2(t, h, o, vp)					\
166     (*((t)->bs_peek_2))((t)->bs_cookie, (h), (o), (vp))
167 
168 #define	bus_space_peek_4(t, h, o, vp)					\
169     (*((t)->bs_peek_4))((t)->bs_cookie, (h), (o), (vp))
170 
171 #if 0	/* Cause a link error for bus_space_peek_8 */
172 #define	bus_space_peek_8(t, h, o, vp)					\
173     (*((t)->bs_peek_8))((t)->bs_cookie, (h), (o), (vp))
174 #endif
175 
176 /*
177  *	int bus_space_poke_N(bus_space_tag_t tag,
178  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t value);
179  *
180  * Cautiously write 1, 2, 4 or 8 byte quantity to bus space described
181  * by tag/handle/offset.
182  * If no hardware responds to the write access, the function returns a
183  * non-zero value.
184  */
185 #define	bus_space_poke_1(t, h, o, v)					\
186     (*((t)->bs_poke_1))((t)->bs_cookie, (h), (o), (v))
187 
188 #define	bus_space_poke_2(t, h, o, v)					\
189     (*((t)->bs_poke_2))((t)->bs_cookie, (h), (o), (v))
190 
191 #define	bus_space_poke_4(t, h, o, v)					\
192     (*((t)->bs_poke_4))((t)->bs_cookie, (h), (o), (v))
193 
194 #if 0	/* Cause a link error for bus_space_poke_8 */
195 #define	bus_space_poke_8(t, h, o, v)					\
196     (*((t)->bs_poke_8))((t)->bs_cookie, (h), (o), (v))
197 #endif
198 
199 /*
200  *	uintN_t bus_space_read_N(bus_space_tag_t tag,
201  *	    bus_space_handle_t bsh, bus_size_t offset);
202  *
203  * Read a 1, 2, 4, or 8 byte quantity from bus space
204  * described by tag/handle/offset.
205  */
206 #define	bus_space_read_1(t,h,o)	\
207 	    (*((volatile uint8_t *)(intptr_t)((h) + (o))))
208 #define	bus_space_read_2(t,h,o)	\
209 	    (*((volatile uint16_t *)(intptr_t)((h) + (o))))
210 #define	bus_space_read_4(t,h,o)	\
211 	    (*((volatile uint32_t *)(intptr_t)((h) + (o))))
212 
213 /*
214  *	void bus_space_read_multi_N(bus_space_tag_t tag,
215  *	    bus_space_handle_t bsh, bus_size_t offset,
216  *	    uintN_t *addr, size_t count);
217  *
218  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
219  * described by tag/handle/offset and copy into buffer provided.
220  */
221 
222 #define	bus_space_read_multi_1(t, h, o, a, c) do {			\
223 	(void) t;							\
224 	__asm volatile ("						\
225 		movl	%0,%%a0					;	\
226 		movl	%1,%%a1					;	\
227 		movl	%2,%%d0					;	\
228 	1:	movb	%%a0@,%%a1@+				;	\
229 		subql	#1,%%d0					;	\
230 		jne	1b"					:	\
231 								:	\
232 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
233 		    "a0","a1","d0");					\
234 } while (0);
235 
236 #define	bus_space_read_multi_2(t, h, o, a, c) do {			\
237 	(void) t;							\
238 	__asm volatile ("						\
239 		movl	%0,%%a0					;	\
240 		movl	%1,%%a1					;	\
241 		movl	%2,%%d0					;	\
242 	1:	movw	%%a0@,%%a1@+				;	\
243 		subql	#1,%%d0					;	\
244 		jne	1b"					:	\
245 								:	\
246 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
247 		    "a0","a1","d0");					\
248 } while (0);
249 
250 #define	bus_space_read_multi_4(t, h, o, a, c) do {			\
251 	(void) t;							\
252 	__asm volatile ("						\
253 		movl	%0,%%a0					;	\
254 		movl	%1,%%a1					;	\
255 		movl	%2,%%d0					;	\
256 	1:	movl	%%a0@,%%a1@+				;	\
257 		subql	#1,%%d0					;	\
258 		jne	1b"					:	\
259 								:	\
260 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
261 		    "a0","a1","d0");					\
262 } while (0);
263 
264 #if 0	/* Cause a link error for bus_space_read_multi_8 */
265 #define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
266 #endif
267 
268 /*
269  *	void bus_space_read_region_N(bus_space_tag_t tag,
270  *	    bus_space_handle_t bsh, bus_size_t offset,
271  *	    uintN_t *addr, size_t count);
272  *
273  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
274  * described by tag/handle and starting at `offset' and copy into
275  * buffer provided.
276  */
277 
278 #define	bus_space_read_region_1(t, h, o, a, c) do {			\
279 	(void) t;							\
280 	__asm volatile ("						\
281 		movl	%0,%%a0					;	\
282 		movl	%1,%%a1					;	\
283 		movl	%2,%%d0					;	\
284 	1:	movb	%%a0@+,%%a1@+				;	\
285 		subql	#1,%%d0					;	\
286 		jne	1b"					:	\
287 								:	\
288 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
289 		    "a0","a1","d0");					\
290 } while (0);
291 
292 #define	bus_space_read_region_2(t, h, o, a, c) do {			\
293 	(void) t;							\
294 	__asm volatile ("						\
295 		movl	%0,%%a0					;	\
296 		movl	%1,%%a1					;	\
297 		movl	%2,%%d0					;	\
298 	1:	movw	%%a0@+,%%a1@+				;	\
299 		subql	#1,%%d0					;	\
300 		jne	1b"					:	\
301 								:	\
302 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
303 		    "a0","a1","d0");					\
304 } while (0);
305 
306 #define	bus_space_read_region_4(t, h, o, a, c) do {			\
307 	(void) t;							\
308 	__asm volatile ("						\
309 		movl	%0,%%a0					;	\
310 		movl	%1,%%a1					;	\
311 		movl	%2,%%d0					;	\
312 	1:	movl	%%a0@+,%%a1@+				;	\
313 		subql	#1,%%d0					;	\
314 		jne	1b"					:	\
315 								:	\
316 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
317 		    "a0","a1","d0");					\
318 } while (0);
319 
320 #if 0	/* Cause a link error for bus_space_read_region_8 */
321 #define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
322 #endif
323 
324 /*
325  *	void bus_space_write_N(bus_space_tag_t tag,
326  *	    bus_space_handle_t bsh, bus_size_t offset,
327  *	    uintN_t value);
328  *
329  * Write the 1, 2, 4, or 8 byte value `value' to bus space
330  * described by tag/handle/offset.
331  */
332 #define	bus_space_write_1(t,h,o,v)					\
333 	do {								\
334 		*((volatile uint8_t *)(intptr_t)((h) + (o))) = (v);	\
335 	} while (/*CONSTCOND*/0)
336 #define	bus_space_write_2(t,h,o,v)					\
337 	do {								\
338 		*((volatile uint16_t *)(intptr_t)((h) + (o))) = (v);	\
339 	} while (/*CONSTCOND*/0)
340 #define	bus_space_write_4(t,h,o,v)					\
341 	do {								\
342 		*((volatile uint32_t *)(intptr_t)((h) + (o))) = (v);	\
343 	} while (/*CONSTCOND*/0)
344 
345 /*
346  *	void bus_space_write_multi_N(bus_space_tag_t tag,
347  *	    bus_space_handle_t bsh, bus_size_t offset,
348  *	    const uintN_t *addr, size_t count);
349  *
350  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
351  * provided to bus space described by tag/handle/offset.
352  */
353 
354 #define	bus_space_write_multi_1(t, h, o, a, c) do {			\
355 	(void) t;							\
356 	__asm volatile ("						\
357 		movl	%0,%%a0					;	\
358 		movl	%1,%%a1					;	\
359 		movl	%2,%%d0					;	\
360 	1:	movb	%%a1@+,%%a0@				;	\
361 		subql	#1,%%d0					;	\
362 		jne	1b"					:	\
363 								:	\
364 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
365 		    "a0","a1","d0");					\
366 } while (0);
367 
368 #define	bus_space_write_multi_2(t, h, o, a, c) do {			\
369 	(void) t;							\
370 	__asm volatile ("						\
371 		movl	%0,%%a0					;	\
372 		movl	%1,%%a1					;	\
373 		movl	%2,%%d0					;	\
374 	1:	movw	%%a1@+,%%a0@				;	\
375 		subql	#1,%%d0					;	\
376 		jne	1b"					:	\
377 								:	\
378 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
379 		    "a0","a1","d0");					\
380 } while (0);
381 
382 #define	bus_space_write_multi_4(t, h, o, a, c) do {			\
383 	(void) t;							\
384 	__asm volatile ("						\
385 		movl	%0,%%a0					;	\
386 		movl	%1,%%a1					;	\
387 		movl	%2,%%d0					;	\
388 	1:	movl	a1@+,%%a0@				;	\
389 		subql	#1,%%d0					;	\
390 		jne	1b"					:	\
391 								:	\
392 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
393 		    "a0","a1","d0");					\
394 } while (0);
395 
396 #if 0	/* Cause a link error for bus_space_write_8 */
397 #define	bus_space_write_multi_8(t, h, o, a, c)				\
398 			!!! bus_space_write_multi_8 unimplimented !!!
399 #endif
400 
401 /*
402  *	void bus_space_write_region_N(bus_space_tag_t tag,
403  *	    bus_space_handle_t bsh, bus_size_t offset,
404  *	    const uintN_t *addr, size_t count);
405  *
406  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
407  * to bus space described by tag/handle starting at `offset'.
408  */
409 
410 #define	bus_space_write_region_1(t, h, o, a, c) do {			\
411 	(void) t;							\
412 	__asm volatile ("						\
413 		movl	%0,%%a0					;	\
414 		movl	%1,%%a1					;	\
415 		movl	%2,%%d0					;	\
416 	1:	movb	%%a1@+,%%a0@+				;	\
417 		subql	#1,%%d0					;	\
418 		jne	1b"					:	\
419 								:	\
420 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
421 		    "a0","a1","d0");					\
422 } while (0);
423 
424 #define	bus_space_write_region_2(t, h, o, a, c) do {			\
425 	(void) t;							\
426 	__asm volatile ("						\
427 		movl	%0,%%a0					;	\
428 		movl	%1,%%a1					;	\
429 		movl	%2,%%d0					;	\
430 	1:	movw	%%a1@+,%%a0@+				;	\
431 		subql	#1,%%d0					;	\
432 		jne	1b"					:	\
433 								:	\
434 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
435 		    "a0","a1","d0");					\
436 } while (0);
437 
438 #define	bus_space_write_region_4(t, h, o, a, c) do {			\
439 	(void) t;							\
440 	__asm volatile ("						\
441 		movl	%0,%%a0					;	\
442 		movl	%1,%%a1					;	\
443 		movl	%2,%%d0					;	\
444 	1:	movl	%%a1@+,%%a0@+				;	\
445 		subql	#1,%%d0					;	\
446 		jne	1b"					:	\
447 								:	\
448 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
449 		    "a0","a1","d0");					\
450 } while (0);
451 
452 #if 0	/* Cause a link error for bus_space_write_region_8 */
453 #define	bus_space_write_region_8					\
454 			!!! bus_space_write_region_8 unimplemented !!!
455 #endif
456 
457 /*
458  *	void bus_space_set_multi_N(bus_space_tag_t tag,
459  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
460  *	    size_t count);
461  *
462  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
463  * by tag/handle/offset `count' times.
464  */
465 
466 #define	bus_space_set_multi_1(t, h, o, val, c) do {			\
467 	(void) t;							\
468 	__asm volatile ("						\
469 		movl	%0,%%a0					;	\
470 		movl	%1,%%d1					;	\
471 		movl	%2,%%d0					;	\
472 	1:	movb	%%d1,%%a0@				;	\
473 		subql	#1,%%d0					;	\
474 		jne	1b"					:	\
475 								:	\
476 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
477 		    "a0","d0","d1");					\
478 } while (0);
479 
480 #define	bus_space_set_multi_2(t, h, o, val, c) do {			\
481 	(void) t;							\
482 	__asm volatile ("						\
483 		movl	%0,%%a0					;	\
484 		movl	%1,%%d1					;	\
485 		movl	%2,%%d0					;	\
486 	1:	movw	%%d1,%%a0@				;	\
487 		subql	#1,%%d0					;	\
488 		jne	1b"					:	\
489 								:	\
490 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
491 		    "a0","d0","d1");					\
492 } while (0);
493 
494 #define	bus_space_set_multi_4(t, h, o, val, c) do {			\
495 	(void) t;							\
496 	__asm volatile ("						\
497 		movl	%0,%%a0					;	\
498 		movl	%1,%%d1					;	\
499 		movl	%2,%%d0					;	\
500 	1:	movl	%%d1,%%a0@				;	\
501 		subql	#1,%%d0					;	\
502 		jne	1b"					:	\
503 								:	\
504 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
505 		    "a0","d0","d1");					\
506 } while (0);
507 
508 #if 0	/* Cause a link error for bus_space_set_multi_8 */
509 #define	bus_space_set_multi_8						\
510 			!!! bus_space_set_multi_8 unimplemented !!!
511 #endif
512 
513 /*
514  *	void bus_space_set_region_N(bus_space_tag_t tag,
515  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
516  *	    size_t count);
517  *
518  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
519  * by tag/handle starting at `offset'.
520  */
521 
522 #define	bus_space_set_region_1(t, h, o, val, c) do {			\
523 	(void) t;							\
524 	__asm volatile ("						\
525 		movl	%0,%%a0					;	\
526 		movl	%1,%%d1					;	\
527 		movl	%2,%%d0					;	\
528 	1:	movb	%%d1,%%a0@+				;	\
529 		subql	#1,%%d0					;	\
530 		jne	1b"					:	\
531 								:	\
532 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
533 		    "a0","d0","d1");					\
534 } while (0);
535 
536 #define	bus_space_set_region_2(t, h, o, val, c) do {			\
537 	(void) t;							\
538 	__asm volatile ("						\
539 		movl	%0,%%a0					;	\
540 		movl	%1,%%d1					;	\
541 		movl	%2,%%d0					;	\
542 	1:	movw	%%d1,%%a0@+				;	\
543 		subql	#1,%%d0					;	\
544 		jne	1b"					:	\
545 								:	\
546 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
547 		    "a0","d0","d1");					\
548 } while (0);
549 
550 #define	bus_space_set_region_4(t, h, o, val, c) do {			\
551 	(void) t;							\
552 	__asm volatile ("						\
553 		movl	%0,%%a0					;	\
554 		movl	%1,%%d1					;	\
555 		movl	%2,%%d0					;	\
556 	1:	movl	d1,%%a0@+				;	\
557 		subql	#1,%%d0					;	\
558 		jne	1b"					:	\
559 								:	\
560 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
561 		    "a0","d0","d1");					\
562 } while (0);
563 
564 #if 0	/* Cause a link error for bus_space_set_region_8 */
565 #define	bus_space_set_region_8						\
566 			!!! bus_space_set_region_8 unimplemented !!!
567 #endif
568 
569 /*
570  *	void bus_space_copy_N(bus_space_tag_t tag,
571  *	    bus_space_handle_t bsh1, bus_size_t off1,
572  *	    bus_space_handle_t bsh2, bus_size_t off2,
573  *	    size_t count);
574  *
575  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
576  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
577  */
578 
579 #define	__MVME68K_copy_region_N(BYTES)					\
580 static __inline void __CONCAT(bus_space_copy_region_,BYTES)		\
581 	(bus_space_tag_t,						\
582 	    bus_space_handle_t bsh1, bus_size_t off1,			\
583 	    bus_space_handle_t bsh2, bus_size_t off2,			\
584 	    bus_size_t count);						\
585 									\
586 static __inline void							\
587 __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c)		\
588 	bus_space_tag_t t;						\
589 	bus_space_handle_t h1, h2;					\
590 	bus_size_t o1, o2, c;						\
591 {									\
592 	bus_size_t o;							\
593 									\
594 	if ((h1 + o1) >= (h2 + o2)) {					\
595 		/* src after dest: copy forward */			\
596 		for (o = 0; c != 0; c--, o += BYTES)			\
597 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
598 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
599 	} else {							\
600 		/* dest after src: copy backwards */			\
601 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
602 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
603 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
604 	}								\
605 }
606 __MVME68K_copy_region_N(1)
607 __MVME68K_copy_region_N(2)
608 __MVME68K_copy_region_N(4)
609 #if 0	/* Cause a link error for bus_space_copy_8 */
610 #define	bus_space_copy_8						\
611 			!!! bus_space_copy_8 unimplemented !!!
612 #endif
613 
614 #undef __MVME68K_copy_region_N
615 
616 /*
617  * Bus read/write barrier methods.
618  *
619  *	void bus_space_barrier(bus_space_tag_t tag,
620  *	    bus_space_handle_t bsh, bus_size_t offset,
621  *	    bus_size_t len, int flags);
622  *
623  * Note: the 680x0 does not currently require barriers, but we must
624  * provide the flags to MI code.
625  */
626 #define	bus_space_barrier(t, h, o, l, f)	\
627 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
628 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
629 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
630 
631 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
632 
633 
634 #ifdef _MVME68K_BUS_SPACE_PRIVATE
635 extern int _bus_space_map(void *, bus_addr_t, bus_size_t,
636     int, bus_space_handle_t *);
637 extern void _bus_space_unmap(void *, bus_space_handle_t, bus_size_t);
638 extern int _bus_space_peek_1(void *, bus_space_handle_t,
639     bus_size_t, uint8_t *);
640 extern int _bus_space_peek_2(void *, bus_space_handle_t,
641     bus_size_t, uint16_t *);
642 extern int _bus_space_peek_4(void *, bus_space_handle_t,
643     bus_size_t, uint32_t *);
644 extern int _bus_space_poke_1(void *, bus_space_handle_t, bus_size_t, uint8_t);
645 extern int _bus_space_poke_2(void *, bus_space_handle_t, bus_size_t, uint16_t);
646 extern int _bus_space_poke_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
647 #endif /* _MVME68K_BUS_SPACE_PRIVATE */
648 
649 #endif /* _MVME68K_BUS_SPACE_H_ */
650