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