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