xref: /netbsd/sys/arch/evbcf/include/bus_space.h (revision 267f2993)
1*267f2993Schristos /*	$NetBSD: bus_space.h,v 1.5 2021/01/23 19:38:07 christos Exp $ */
27168dfe8Smatt 
37168dfe8Smatt /*-
47168dfe8Smatt  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
57168dfe8Smatt  * All rights reserved.
67168dfe8Smatt  *
77168dfe8Smatt  * This code is derived from software contributed to The NetBSD Foundation
87168dfe8Smatt  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
97168dfe8Smatt  * NASA Ames Research Center.
107168dfe8Smatt  *
117168dfe8Smatt  * Redistribution and use in source and binary forms, with or without
127168dfe8Smatt  * modification, are permitted provided that the following conditions
137168dfe8Smatt  * are met:
147168dfe8Smatt  * 1. Redistributions of source code must retain the above copyright
157168dfe8Smatt  *    notice, this list of conditions and the following disclaimer.
167168dfe8Smatt  * 2. Redistributions in binary form must reproduce the above copyright
177168dfe8Smatt  *    notice, this list of conditions and the following disclaimer in the
187168dfe8Smatt  *    documentation and/or other materials provided with the distribution.
197168dfe8Smatt  *
207168dfe8Smatt  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
217168dfe8Smatt  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
227168dfe8Smatt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
237168dfe8Smatt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
247168dfe8Smatt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
257168dfe8Smatt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
267168dfe8Smatt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
277168dfe8Smatt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
287168dfe8Smatt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
297168dfe8Smatt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
307168dfe8Smatt  * POSSIBILITY OF SUCH DAMAGE.
317168dfe8Smatt  */
327168dfe8Smatt 
337168dfe8Smatt /*
347168dfe8Smatt  * Copyright (C) 1997 Scott Reynolds.  All rights reserved.
357168dfe8Smatt  *
367168dfe8Smatt  * Redistribution and use in source and binary forms, with or without
377168dfe8Smatt  * modification, are permitted provided that the following conditions
387168dfe8Smatt  * are met:
397168dfe8Smatt  * 1. Redistributions of source code must retain the above copyright
407168dfe8Smatt  *    notice, this list of conditions and the following disclaimer.
417168dfe8Smatt  * 2. Redistributions in binary form must reproduce the above copyright
427168dfe8Smatt  *    notice, this list of conditions and the following disclaimer in the
437168dfe8Smatt  *    documentation and/or other materials provided with the distribution.
447168dfe8Smatt  * 3. The name of the author may not be used to endorse or promote products
457168dfe8Smatt  *    derived from this software without specific prior written permission
467168dfe8Smatt  *
477168dfe8Smatt  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
487168dfe8Smatt  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
497168dfe8Smatt  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
507168dfe8Smatt  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
517168dfe8Smatt  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
527168dfe8Smatt  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
537168dfe8Smatt  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
547168dfe8Smatt  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
557168dfe8Smatt  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
567168dfe8Smatt  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
577168dfe8Smatt  */
587168dfe8Smatt 
597168dfe8Smatt /*
607168dfe8Smatt  * Lifted from the Next68k port.
617168dfe8Smatt  * Modified for mvme68k by Steve Woodford.
627168dfe8Smatt  * Modified for evbcf by Steve Woodford.
637168dfe8Smatt  */
647168dfe8Smatt 
657168dfe8Smatt #ifndef _EVBCF_BUS_SPACE_H_
667168dfe8Smatt #define	_EVBCF_BUS_SPACE_H_
677168dfe8Smatt 
687168dfe8Smatt /*
697168dfe8Smatt  * Addresses (in bus space).
707168dfe8Smatt  */
717168dfe8Smatt typedef u_long bus_addr_t;
727168dfe8Smatt typedef u_long bus_size_t;
737168dfe8Smatt 
748a06b90dSskrll #define PRIxBUSADDR	"lx"
758a06b90dSskrll #define PRIxBUSSIZE	"lx"
768a06b90dSskrll #define PRIuBUSSIZE	"lu"
777168dfe8Smatt /*
787168dfe8Smatt  * Access methods for bus resources and address space.
797168dfe8Smatt  */
807168dfe8Smatt struct mvme68k_bus_space_tag;
817168dfe8Smatt typedef struct mvme68k_bus_space_tag	*bus_space_tag_t;
827168dfe8Smatt typedef u_long	bus_space_handle_t;
837168dfe8Smatt 
848a06b90dSskrll #define PRIxBSH		"lx"
858a06b90dSskrll 
867168dfe8Smatt struct mvme68k_bus_space_tag {
877168dfe8Smatt 	void		*bs_cookie;
887168dfe8Smatt 	int		(*bs_map)(void *, bus_addr_t, bus_size_t,
897168dfe8Smatt 				  int, bus_space_handle_t *);
907168dfe8Smatt 	void		(*bs_unmap)(void *, bus_space_handle_t, bus_size_t);
917168dfe8Smatt 	int		(*bs_peek_1)(void *, bus_space_handle_t,
927168dfe8Smatt 				     bus_size_t, uint8_t *);
937168dfe8Smatt 	int		(*bs_peek_2)(void *, bus_space_handle_t,
947168dfe8Smatt 				     bus_size_t, uint16_t *);
957168dfe8Smatt 	int		(*bs_peek_4)(void *, bus_space_handle_t,
967168dfe8Smatt 				     bus_size_t, uint32_t *);
977168dfe8Smatt #if 0
987168dfe8Smatt 	int		(*bs_peek_8)(void *, bus_space_handle_t,
997168dfe8Smatt 				     bus_size_t, uint64_t *);
1007168dfe8Smatt #endif
1017168dfe8Smatt 	int		(*bs_poke_1)(void *, bus_space_handle_t,
1027168dfe8Smatt 				     bus_size_t, uint8_t);
1037168dfe8Smatt 	int		(*bs_poke_2)(void *, bus_space_handle_t,
1047168dfe8Smatt 				     bus_size_t, uint16_t);
1057168dfe8Smatt 	int		(*bs_poke_4)(void *, bus_space_handle_t,
1067168dfe8Smatt 				     bus_size_t, uint32_t);
1077168dfe8Smatt #if 0
1087168dfe8Smatt 	int		(*bs_poke_8)(void *, bus_space_handle_t,
1097168dfe8Smatt 				     bus_size_t, uint64_t);
1107168dfe8Smatt #endif
1117168dfe8Smatt };
1127168dfe8Smatt 
1137168dfe8Smatt /*
1147168dfe8Smatt  *	int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
1157168dfe8Smatt  *	                  bus_size_t size, int flags,
1167168dfe8Smatt  *                        bus_space_handle_t *bshp);
1177168dfe8Smatt  *
1187168dfe8Smatt  * Map a region of bus space.
1197168dfe8Smatt  */
1207168dfe8Smatt #define	bus_space_map(tag, offset, size, flags, handlep)		\
1217168dfe8Smatt     (*((tag)->bs_map))((tag)->bs_cookie, (offset), (size), (flags), (handlep))
1227168dfe8Smatt 
1237168dfe8Smatt /*
1247168dfe8Smatt  * Possible values for the 'flags' parameter of bus_space_map()
1257168dfe8Smatt  */
1267168dfe8Smatt #define	BUS_SPACE_MAP_CACHEABLE		0x01
1277168dfe8Smatt #define	BUS_SPACE_MAP_LINEAR		0x02
1287168dfe8Smatt #define	BUS_SPACE_MAP_PREFETCHABLE	0x04
1297168dfe8Smatt 
1307168dfe8Smatt /*
1317168dfe8Smatt  *	void bus_space_unmap(bus_space_tag_t t,
1327168dfe8Smatt  *                           bus_space_handle_t bsh, bus_size_t size);
1337168dfe8Smatt  *
1347168dfe8Smatt  * Unmap a region of bus space.
1357168dfe8Smatt  */
1367168dfe8Smatt #define bus_space_unmap(tag, handle, size)				\
1377168dfe8Smatt     (*((tag)->bs_unmap))((tag)->bs_cookie, (handle), (size))
1387168dfe8Smatt 
1397168dfe8Smatt /*
1407168dfe8Smatt  *	int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t h
1417168dfe8Smatt  *	    bus_addr_t offset, bus_size_t size, bus_space_handle_t *newh);
1427168dfe8Smatt  *
1437168dfe8Smatt  * Allocate a sub-region of an existing map
1447168dfe8Smatt  */
1457168dfe8Smatt #define	bus_space_subregion(t, h, o, s, hp)				\
1467168dfe8Smatt      ((*(hp)=(h)+(o)), 0)
1477168dfe8Smatt 
1487168dfe8Smatt /*
1497168dfe8Smatt  * Allocation and deallocation operations.
1507168dfe8Smatt  */
1517168dfe8Smatt #define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)  		\
1527168dfe8Smatt      (-1)
1537168dfe8Smatt 
1547168dfe8Smatt #define	bus_space_free(t, h, s)
1557168dfe8Smatt 
1567168dfe8Smatt /*
1577168dfe8Smatt  *	int bus_space_peek_N(bus_space_tag_t tag,
1587168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t *valuep);
1597168dfe8Smatt  *
1607168dfe8Smatt  * Cautiously read 1, 2, 4 or 8 byte quantity from bus space described
1617168dfe8Smatt  * by tag/handle/offset.
1627168dfe8Smatt  * If no hardware responds to the read access, the function returns a
1637168dfe8Smatt  * non-zero value. Otherwise the value read is placed in `valuep'.
1647168dfe8Smatt  */
1657168dfe8Smatt #define	bus_space_peek_1(t, h, o, vp)					\
1667168dfe8Smatt     (*((t)->bs_peek_1))((t)->bs_cookie, (h), (o), (vp))
1677168dfe8Smatt 
1687168dfe8Smatt #define	bus_space_peek_2(t, h, o, vp)					\
1697168dfe8Smatt     (*((t)->bs_peek_2))((t)->bs_cookie, (h), (o), (vp))
1707168dfe8Smatt 
1717168dfe8Smatt #define	bus_space_peek_4(t, h, o, vp)					\
1727168dfe8Smatt     (*((t)->bs_peek_4))((t)->bs_cookie, (h), (o), (vp))
1737168dfe8Smatt 
1747168dfe8Smatt /*
1757168dfe8Smatt  *	int bus_space_poke_N(bus_space_tag_t tag,
1767168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t value);
1777168dfe8Smatt  *
1787168dfe8Smatt  * Cautiously write 1, 2, 4 or 8 byte quantity to bus space described
1797168dfe8Smatt  * by tag/handle/offset.
1807168dfe8Smatt  * If no hardware responds to the write access, the function returns a
1817168dfe8Smatt  * non-zero value.
1827168dfe8Smatt  */
1837168dfe8Smatt #define	bus_space_poke_1(t, h, o, v)					\
1847168dfe8Smatt     (*((t)->bs_poke_1))((t)->bs_cookie, (h), (o), (v))
1857168dfe8Smatt 
1867168dfe8Smatt #define	bus_space_poke_2(t, h, o, v)					\
1877168dfe8Smatt     (*((t)->bs_poke_2))((t)->bs_cookie, (h), (o), (v))
1887168dfe8Smatt 
1897168dfe8Smatt #define	bus_space_poke_4(t, h, o, v)					\
1907168dfe8Smatt     (*((t)->bs_poke_4))((t)->bs_cookie, (h), (o), (v))
1917168dfe8Smatt 
1927168dfe8Smatt /*
1937168dfe8Smatt  *	uintN_t bus_space_read_N(bus_space_tag_t tag,
1947168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset);
1957168dfe8Smatt  *
1967168dfe8Smatt  * Read a 1, 2, 4, or 8 byte quantity from bus space
1977168dfe8Smatt  * described by tag/handle/offset.
1987168dfe8Smatt  */
1997168dfe8Smatt #define	bus_space_read_1(t,h,o)	\
2007168dfe8Smatt 	    (*((volatile uint8_t *)(intptr_t)((h) + (o))))
2017168dfe8Smatt #define	bus_space_read_2(t,h,o)	\
2027168dfe8Smatt 	    (*((volatile uint16_t *)(intptr_t)((h) + (o))))
2037168dfe8Smatt #define	bus_space_read_4(t,h,o)	\
2047168dfe8Smatt 	    (*((volatile uint32_t *)(intptr_t)((h) + (o))))
2057168dfe8Smatt 
2067168dfe8Smatt /*
2077168dfe8Smatt  *	void bus_space_read_multi_N(bus_space_tag_t tag,
2087168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset,
2097168dfe8Smatt  *	    uintN_t *addr, size_t count);
2107168dfe8Smatt  *
2117168dfe8Smatt  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
2127168dfe8Smatt  * described by tag/handle/offset and copy into buffer provided.
2137168dfe8Smatt  */
2147168dfe8Smatt 
2157168dfe8Smatt #define	bus_space_read_multi_1(t, h, o, a, c) do {			\
2167168dfe8Smatt 	(void) t;							\
2177168dfe8Smatt 	__asm volatile ("						\
2187168dfe8Smatt 		movl	%0,%%a0					;	\
2197168dfe8Smatt 		movl	%1,%%a1					;	\
2207168dfe8Smatt 		movl	%2,%%d0					;	\
2217168dfe8Smatt 	1:	movb	%%a0@,%%a1@+				;	\
2227168dfe8Smatt 		subql	#1,%%d0					;	\
2237168dfe8Smatt 		jne	1b"					:	\
2247168dfe8Smatt 								:	\
2257168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
2267168dfe8Smatt 		    "a0","a1","d0");					\
2277168dfe8Smatt } while (0);
2287168dfe8Smatt 
2297168dfe8Smatt #define	bus_space_read_multi_2(t, h, o, a, c) do {			\
2307168dfe8Smatt 	(void) t;							\
2317168dfe8Smatt 	__asm volatile ("						\
2327168dfe8Smatt 		movl	%0,%%a0					;	\
2337168dfe8Smatt 		movl	%1,%%a1					;	\
2347168dfe8Smatt 		movl	%2,%%d0					;	\
2357168dfe8Smatt 	1:	movw	%%a0@,%%a1@+				;	\
2367168dfe8Smatt 		subql	#1,%%d0					;	\
2377168dfe8Smatt 		jne	1b"					:	\
2387168dfe8Smatt 								:	\
2397168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
2407168dfe8Smatt 		    "a0","a1","d0");					\
2417168dfe8Smatt } while (0);
2427168dfe8Smatt 
2437168dfe8Smatt #define	bus_space_read_multi_4(t, h, o, a, c) do {			\
2447168dfe8Smatt 	(void) t;							\
2457168dfe8Smatt 	__asm volatile ("						\
2467168dfe8Smatt 		movl	%0,%%a0					;	\
2477168dfe8Smatt 		movl	%1,%%a1					;	\
2487168dfe8Smatt 		movl	%2,%%d0					;	\
2497168dfe8Smatt 	1:	movl	%%a0@,%%a1@+				;	\
2507168dfe8Smatt 		subql	#1,%%d0					;	\
2517168dfe8Smatt 		jne	1b"					:	\
2527168dfe8Smatt 								:	\
2537168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
2547168dfe8Smatt 		    "a0","a1","d0");					\
2557168dfe8Smatt } while (0);
2567168dfe8Smatt 
2577168dfe8Smatt /*
2587168dfe8Smatt  *	void bus_space_read_region_N(bus_space_tag_t tag,
2597168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset,
2607168dfe8Smatt  *	    uintN_t *addr, size_t count);
2617168dfe8Smatt  *
2627168dfe8Smatt  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
2637168dfe8Smatt  * described by tag/handle and starting at `offset' and copy into
2647168dfe8Smatt  * buffer provided.
2657168dfe8Smatt  */
2667168dfe8Smatt 
2677168dfe8Smatt #define	bus_space_read_region_1(t, h, o, a, c) do {			\
2687168dfe8Smatt 	(void) t;							\
2697168dfe8Smatt 	__asm volatile ("						\
2707168dfe8Smatt 		movl	%0,%%a0					;	\
2717168dfe8Smatt 		movl	%1,%%a1					;	\
2727168dfe8Smatt 		movl	%2,%%d0					;	\
2737168dfe8Smatt 	1:	movb	%%a0@+,%%a1@+				;	\
2747168dfe8Smatt 		subql	#1,%%d0					;	\
2757168dfe8Smatt 		jne	1b"					:	\
2767168dfe8Smatt 								:	\
2777168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
2787168dfe8Smatt 		    "a0","a1","d0");					\
2797168dfe8Smatt } while (0);
2807168dfe8Smatt 
2817168dfe8Smatt #define	bus_space_read_region_2(t, h, o, a, c) do {			\
2827168dfe8Smatt 	(void) t;							\
2837168dfe8Smatt 	__asm volatile ("						\
2847168dfe8Smatt 		movl	%0,%%a0					;	\
2857168dfe8Smatt 		movl	%1,%%a1					;	\
2867168dfe8Smatt 		movl	%2,%%d0					;	\
2877168dfe8Smatt 	1:	movw	%%a0@+,%%a1@+				;	\
2887168dfe8Smatt 		subql	#1,%%d0					;	\
2897168dfe8Smatt 		jne	1b"					:	\
2907168dfe8Smatt 								:	\
2917168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
2927168dfe8Smatt 		    "a0","a1","d0");					\
2937168dfe8Smatt } while (0);
2947168dfe8Smatt 
2957168dfe8Smatt #define	bus_space_read_region_4(t, h, o, a, c) do {			\
2967168dfe8Smatt 	(void) t;							\
2977168dfe8Smatt 	__asm volatile ("						\
2987168dfe8Smatt 		movl	%0,%%a0					;	\
2997168dfe8Smatt 		movl	%1,%%a1					;	\
3007168dfe8Smatt 		movl	%2,%%d0					;	\
3017168dfe8Smatt 	1:	movl	%%a0@+,%%a1@+				;	\
3027168dfe8Smatt 		subql	#1,%%d0					;	\
3037168dfe8Smatt 		jne	1b"					:	\
3047168dfe8Smatt 								:	\
3057168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
3067168dfe8Smatt 		    "a0","a1","d0");					\
3077168dfe8Smatt } while (0);
3087168dfe8Smatt 
3097168dfe8Smatt /*
3107168dfe8Smatt  *	void bus_space_write_N(bus_space_tag_t tag,
3117168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset,
3127168dfe8Smatt  *	    uintN_t value);
3137168dfe8Smatt  *
3147168dfe8Smatt  * Write the 1, 2, 4, or 8 byte value `value' to bus space
3157168dfe8Smatt  * described by tag/handle/offset.
3167168dfe8Smatt  */
3177168dfe8Smatt #define	bus_space_write_1(t,h,o,v)					\
3187168dfe8Smatt 	do {								\
3197168dfe8Smatt 		*((volatile uint8_t *)(intptr_t)((h) + (o))) = (v);	\
3207168dfe8Smatt 	} while (/*CONSTCOND*/0)
3217168dfe8Smatt #define	bus_space_write_2(t,h,o,v)					\
3227168dfe8Smatt 	do {								\
3237168dfe8Smatt 		*((volatile uint16_t *)(intptr_t)((h) + (o))) = (v);	\
3247168dfe8Smatt 	} while (/*CONSTCOND*/0)
3257168dfe8Smatt #define	bus_space_write_4(t,h,o,v)					\
3267168dfe8Smatt 	do {								\
3277168dfe8Smatt 		*((volatile uint32_t *)(intptr_t)((h) + (o))) = (v);	\
3287168dfe8Smatt 	} while (/*CONSTCOND*/0)
3297168dfe8Smatt 
3307168dfe8Smatt /*
3317168dfe8Smatt  *	void bus_space_write_multi_N(bus_space_tag_t tag,
3327168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset,
3337168dfe8Smatt  *	    const uintN_t *addr, size_t count);
3347168dfe8Smatt  *
3357168dfe8Smatt  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
3367168dfe8Smatt  * provided to bus space described by tag/handle/offset.
3377168dfe8Smatt  */
3387168dfe8Smatt 
3397168dfe8Smatt #define	bus_space_write_multi_1(t, h, o, a, c) do {			\
3407168dfe8Smatt 	(void) t;							\
3417168dfe8Smatt 	__asm volatile ("						\
3427168dfe8Smatt 		movl	%0,%%a0					;	\
3437168dfe8Smatt 		movl	%1,%%a1					;	\
3447168dfe8Smatt 		movl	%2,%%d0					;	\
3457168dfe8Smatt 	1:	movb	%%a1@+,%%a0@				;	\
3467168dfe8Smatt 		subql	#1,%%d0					;	\
3477168dfe8Smatt 		jne	1b"					:	\
3487168dfe8Smatt 								:	\
3497168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
3507168dfe8Smatt 		    "a0","a1","d0");					\
3517168dfe8Smatt } while (0);
3527168dfe8Smatt 
3537168dfe8Smatt #define	bus_space_write_multi_2(t, h, o, a, c) do {			\
3547168dfe8Smatt 	(void) t;							\
3557168dfe8Smatt 	__asm volatile ("						\
3567168dfe8Smatt 		movl	%0,%%a0					;	\
3577168dfe8Smatt 		movl	%1,%%a1					;	\
3587168dfe8Smatt 		movl	%2,%%d0					;	\
3597168dfe8Smatt 	1:	movw	%%a1@+,%%a0@				;	\
3607168dfe8Smatt 		subql	#1,%%d0					;	\
3617168dfe8Smatt 		jne	1b"					:	\
3627168dfe8Smatt 								:	\
3637168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
3647168dfe8Smatt 		    "a0","a1","d0");					\
3657168dfe8Smatt } while (0);
3667168dfe8Smatt 
3677168dfe8Smatt #define	bus_space_write_multi_4(t, h, o, a, c) do {			\
3687168dfe8Smatt 	(void) t;							\
3697168dfe8Smatt 	__asm volatile ("						\
3707168dfe8Smatt 		movl	%0,%%a0					;	\
3717168dfe8Smatt 		movl	%1,%%a1					;	\
3727168dfe8Smatt 		movl	%2,%%d0					;	\
3737168dfe8Smatt 	1:	movl	a1@+,%%a0@				;	\
3747168dfe8Smatt 		subql	#1,%%d0					;	\
3757168dfe8Smatt 		jne	1b"					:	\
3767168dfe8Smatt 								:	\
3777168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
3787168dfe8Smatt 		    "a0","a1","d0");					\
3797168dfe8Smatt } while (0);
3807168dfe8Smatt 
3817168dfe8Smatt /*
3827168dfe8Smatt  *	void bus_space_write_region_N(bus_space_tag_t tag,
3837168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset,
3847168dfe8Smatt  *	    const uintN_t *addr, size_t count);
3857168dfe8Smatt  *
3867168dfe8Smatt  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
3877168dfe8Smatt  * to bus space described by tag/handle starting at `offset'.
3887168dfe8Smatt  */
3897168dfe8Smatt 
3907168dfe8Smatt #define	bus_space_write_region_1(t, h, o, a, c) do {			\
3917168dfe8Smatt 	(void) t;							\
3927168dfe8Smatt 	__asm volatile ("						\
3937168dfe8Smatt 		movl	%0,%%a0					;	\
3947168dfe8Smatt 		movl	%1,%%a1					;	\
3957168dfe8Smatt 		movl	%2,%%d0					;	\
3967168dfe8Smatt 	1:	movb	%%a1@+,%%a0@+				;	\
3977168dfe8Smatt 		subql	#1,%%d0					;	\
3987168dfe8Smatt 		jne	1b"					:	\
3997168dfe8Smatt 								:	\
4007168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
4017168dfe8Smatt 		    "a0","a1","d0");					\
4027168dfe8Smatt } while (0);
4037168dfe8Smatt 
4047168dfe8Smatt #define	bus_space_write_region_2(t, h, o, a, c) do {			\
4057168dfe8Smatt 	(void) t;							\
4067168dfe8Smatt 	__asm volatile ("						\
4077168dfe8Smatt 		movl	%0,%%a0					;	\
4087168dfe8Smatt 		movl	%1,%%a1					;	\
4097168dfe8Smatt 		movl	%2,%%d0					;	\
4107168dfe8Smatt 	1:	movw	%%a1@+,%%a0@+				;	\
4117168dfe8Smatt 		subql	#1,%%d0					;	\
4127168dfe8Smatt 		jne	1b"					:	\
4137168dfe8Smatt 								:	\
4147168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
4157168dfe8Smatt 		    "a0","a1","d0");					\
4167168dfe8Smatt } while (0);
4177168dfe8Smatt 
4187168dfe8Smatt #define	bus_space_write_region_4(t, h, o, a, c) do {			\
4197168dfe8Smatt 	(void) t;							\
4207168dfe8Smatt 	__asm volatile ("						\
4217168dfe8Smatt 		movl	%0,%%a0					;	\
4227168dfe8Smatt 		movl	%1,%%a1					;	\
4237168dfe8Smatt 		movl	%2,%%d0					;	\
4247168dfe8Smatt 	1:	movl	%%a1@+,%%a0@+				;	\
4257168dfe8Smatt 		subql	#1,%%d0					;	\
4267168dfe8Smatt 		jne	1b"					:	\
4277168dfe8Smatt 								:	\
4287168dfe8Smatt 		    "r" ((h) + (o)), "g" (a), "g" (c)		:	\
4297168dfe8Smatt 		    "a0","a1","d0");					\
4307168dfe8Smatt } while (0);
4317168dfe8Smatt 
4327168dfe8Smatt /*
4337168dfe8Smatt  *	void bus_space_set_multi_N(bus_space_tag_t tag,
4347168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
4357168dfe8Smatt  *	    size_t count);
4367168dfe8Smatt  *
4377168dfe8Smatt  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
4387168dfe8Smatt  * by tag/handle/offset `count' times.
4397168dfe8Smatt  */
4407168dfe8Smatt 
4417168dfe8Smatt #define	bus_space_set_multi_1(t, h, o, val, c) do {			\
4427168dfe8Smatt 	(void) t;							\
4437168dfe8Smatt 	__asm volatile ("						\
4447168dfe8Smatt 		movl	%0,%%a0					;	\
4457168dfe8Smatt 		movl	%1,%%d1					;	\
4467168dfe8Smatt 		movl	%2,%%d0					;	\
4477168dfe8Smatt 	1:	movb	%%d1,%%a0@				;	\
4487168dfe8Smatt 		subql	#1,%%d0					;	\
4497168dfe8Smatt 		jne	1b"					:	\
4507168dfe8Smatt 								:	\
4517168dfe8Smatt 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
4527168dfe8Smatt 		    "a0","d0","d1");					\
4537168dfe8Smatt } while (0);
4547168dfe8Smatt 
4557168dfe8Smatt #define	bus_space_set_multi_2(t, h, o, val, c) do {			\
4567168dfe8Smatt 	(void) t;							\
4577168dfe8Smatt 	__asm volatile ("						\
4587168dfe8Smatt 		movl	%0,%%a0					;	\
4597168dfe8Smatt 		movl	%1,%%d1					;	\
4607168dfe8Smatt 		movl	%2,%%d0					;	\
4617168dfe8Smatt 	1:	movw	%%d1,%%a0@				;	\
4627168dfe8Smatt 		subql	#1,%%d0					;	\
4637168dfe8Smatt 		jne	1b"					:	\
4647168dfe8Smatt 								:	\
4657168dfe8Smatt 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
4667168dfe8Smatt 		    "a0","d0","d1");					\
4677168dfe8Smatt } while (0);
4687168dfe8Smatt 
4697168dfe8Smatt #define	bus_space_set_multi_4(t, h, o, val, c) do {			\
4707168dfe8Smatt 	(void) t;							\
4717168dfe8Smatt 	__asm volatile ("						\
4727168dfe8Smatt 		movl	%0,%%a0					;	\
4737168dfe8Smatt 		movl	%1,%%d1					;	\
4747168dfe8Smatt 		movl	%2,%%d0					;	\
4757168dfe8Smatt 	1:	movl	%%d1,%%a0@				;	\
4767168dfe8Smatt 		subql	#1,%%d0					;	\
4777168dfe8Smatt 		jne	1b"					:	\
4787168dfe8Smatt 								:	\
4797168dfe8Smatt 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
4807168dfe8Smatt 		    "a0","d0","d1");					\
4817168dfe8Smatt } while (0);
4827168dfe8Smatt 
4837168dfe8Smatt /*
4847168dfe8Smatt  *	void bus_space_set_region_N(bus_space_tag_t tag,
4857168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
4867168dfe8Smatt  *	    size_t count);
4877168dfe8Smatt  *
4887168dfe8Smatt  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
4897168dfe8Smatt  * by tag/handle starting at `offset'.
4907168dfe8Smatt  */
4917168dfe8Smatt 
4927168dfe8Smatt #define	bus_space_set_region_1(t, h, o, val, c) do {			\
4937168dfe8Smatt 	(void) t;							\
4947168dfe8Smatt 	__asm volatile ("						\
4957168dfe8Smatt 		movl	%0,%%a0					;	\
4967168dfe8Smatt 		movl	%1,%%d1					;	\
4977168dfe8Smatt 		movl	%2,%%d0					;	\
4987168dfe8Smatt 	1:	movb	%%d1,%%a0@+				;	\
4997168dfe8Smatt 		subql	#1,%%d0					;	\
5007168dfe8Smatt 		jne	1b"					:	\
5017168dfe8Smatt 								:	\
5027168dfe8Smatt 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
5037168dfe8Smatt 		    "a0","d0","d1");					\
5047168dfe8Smatt } while (0);
5057168dfe8Smatt 
5067168dfe8Smatt #define	bus_space_set_region_2(t, h, o, val, c) do {			\
5077168dfe8Smatt 	(void) t;							\
5087168dfe8Smatt 	__asm volatile ("						\
5097168dfe8Smatt 		movl	%0,%%a0					;	\
5107168dfe8Smatt 		movl	%1,%%d1					;	\
5117168dfe8Smatt 		movl	%2,%%d0					;	\
5127168dfe8Smatt 	1:	movw	%%d1,%%a0@+				;	\
5137168dfe8Smatt 		subql	#1,%%d0					;	\
5147168dfe8Smatt 		jne	1b"					:	\
5157168dfe8Smatt 								:	\
5167168dfe8Smatt 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
5177168dfe8Smatt 		    "a0","d0","d1");					\
5187168dfe8Smatt } while (0);
5197168dfe8Smatt 
5207168dfe8Smatt #define	bus_space_set_region_4(t, h, o, val, c) do {			\
5217168dfe8Smatt 	(void) t;							\
5227168dfe8Smatt 	__asm volatile ("						\
5237168dfe8Smatt 		movl	%0,%%a0					;	\
5247168dfe8Smatt 		movl	%1,%%d1					;	\
5257168dfe8Smatt 		movl	%2,%%d0					;	\
5267168dfe8Smatt 	1:	movl	d1,%%a0@+				;	\
5277168dfe8Smatt 		subql	#1,%%d0					;	\
5287168dfe8Smatt 		jne	1b"					:	\
5297168dfe8Smatt 								:	\
5307168dfe8Smatt 		    "r" ((h) + (o)), "g" (val), "g" (c)		:	\
5317168dfe8Smatt 		    "a0","d0","d1");					\
5327168dfe8Smatt } while (0);
5337168dfe8Smatt 
5347168dfe8Smatt /*
5357168dfe8Smatt  *	void bus_space_copy_N(bus_space_tag_t tag,
5367168dfe8Smatt  *	    bus_space_handle_t bsh1, bus_size_t off1,
5377168dfe8Smatt  *	    bus_space_handle_t bsh2, bus_size_t off2,
5387168dfe8Smatt  *	    size_t count);
5397168dfe8Smatt  *
5407168dfe8Smatt  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
5417168dfe8Smatt  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
5427168dfe8Smatt  */
5437168dfe8Smatt 
5447168dfe8Smatt #define	__COLDFIRE_copy_region_N(BYTES)					\
5457168dfe8Smatt static __inline void __CONCAT(bus_space_copy_region_,BYTES)		\
5467168dfe8Smatt 	(bus_space_tag_t,						\
5477168dfe8Smatt 	    bus_space_handle_t bsh1, bus_size_t off1,			\
5487168dfe8Smatt 	    bus_space_handle_t bsh2, bus_size_t off2,			\
5497168dfe8Smatt 	    bus_size_t count);						\
5507168dfe8Smatt 									\
5517168dfe8Smatt static __inline void							\
5527168dfe8Smatt __CONCAT(bus_space_copy_region_,BYTES)(					\
5537168dfe8Smatt 	bus_space_tag_t t,						\
5547168dfe8Smatt 	bus_space_handle_t h1,						\
5557168dfe8Smatt 	bus_size_t o1,							\
5567168dfe8Smatt 	bus_space_handle_t h2,						\
5577168dfe8Smatt 	bus_size_t o2,							\
5587168dfe8Smatt 	bus_size_t c)							\
5597168dfe8Smatt {									\
5607168dfe8Smatt 	bus_size_t o;							\
5617168dfe8Smatt 									\
5627168dfe8Smatt 	if ((h1 + o1) >= (h2 + o2)) {					\
5637168dfe8Smatt 		/* src after dest: copy forward */			\
5647168dfe8Smatt 		for (o = 0; c != 0; c--, o += BYTES)			\
5657168dfe8Smatt 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
5667168dfe8Smatt 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
5677168dfe8Smatt 	} else {							\
5687168dfe8Smatt 		/* dest after src: copy backwards */			\
5697168dfe8Smatt 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
5707168dfe8Smatt 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
5717168dfe8Smatt 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
5727168dfe8Smatt 	}								\
5737168dfe8Smatt }
5747168dfe8Smatt __COLDFIRE_copy_region_N(1)
5757168dfe8Smatt __COLDFIRE_copy_region_N(2)
5767168dfe8Smatt __COLDFIRE_copy_region_N(4)
5777168dfe8Smatt 
5787168dfe8Smatt #undef __COLDFIRE_copy_region_N
5797168dfe8Smatt 
5807168dfe8Smatt /*
5817168dfe8Smatt  * Bus read/write barrier methods.
5827168dfe8Smatt  *
5837168dfe8Smatt  *	void bus_space_barrier(bus_space_tag_t tag,
5847168dfe8Smatt  *	    bus_space_handle_t bsh, bus_size_t offset,
5857168dfe8Smatt  *	    bus_size_t len, int flags);
5867168dfe8Smatt  *
5877168dfe8Smatt  * Note: Coldfire does not currently require barriers, but we must
5887168dfe8Smatt  * provide the flags to MI code.
5897168dfe8Smatt  */
5907168dfe8Smatt #define	bus_space_barrier(t, h, o, l, f)	\
5917168dfe8Smatt 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
5927168dfe8Smatt #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
5937168dfe8Smatt #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
5947168dfe8Smatt 
5957168dfe8Smatt #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
5967168dfe8Smatt 
5977168dfe8Smatt 
5987168dfe8Smatt #ifdef _COLDFIRE_BUS_SPACE_PRIVATE
5997168dfe8Smatt extern int _bus_space_map(void *, bus_addr_t, bus_size_t,
6007168dfe8Smatt     int, bus_space_handle_t *);
6017168dfe8Smatt extern void _bus_space_unmap(void *, bus_space_handle_t, bus_size_t);
6027168dfe8Smatt extern int _bus_space_peek_1(void *, bus_space_handle_t,
6037168dfe8Smatt     bus_size_t, uint8_t *);
6047168dfe8Smatt extern int _bus_space_peek_2(void *, bus_space_handle_t,
6057168dfe8Smatt     bus_size_t, uint16_t *);
6067168dfe8Smatt extern int _bus_space_peek_4(void *, bus_space_handle_t,
6077168dfe8Smatt     bus_size_t, uint32_t *);
6087168dfe8Smatt extern int _bus_space_poke_1(void *, bus_space_handle_t, bus_size_t, uint8_t);
6097168dfe8Smatt extern int _bus_space_poke_2(void *, bus_space_handle_t, bus_size_t, uint16_t);
6107168dfe8Smatt extern int _bus_space_poke_4(void *, bus_space_handle_t, bus_size_t, uint32_t);
6117168dfe8Smatt #endif /* _COLDFIRE_BUS_SPACE_PRIVATE */
6127168dfe8Smatt 
6137168dfe8Smatt #endif /* _EVBCF_BUS_SPACE_H_ */
614