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