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