bus.h revision 1.3
11.3Ssimonb/*	$NetBSD: bus.h,v 1.3 2000/06/26 04:55:57 simonb Exp $	*/
21.1Snonaka/*	$OpenBSD: bus.h,v 1.1 1997/10/13 10:53:42 pefo Exp $	*/
31.1Snonaka
41.1Snonaka/*-
51.1Snonaka * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
61.1Snonaka * All rights reserved.
71.1Snonaka *
81.1Snonaka * This code is derived from software contributed to The NetBSD Foundation
91.1Snonaka * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
101.1Snonaka * NASA Ames Research Center.
111.1Snonaka *
121.1Snonaka * Redistribution and use in source and binary forms, with or without
131.1Snonaka * modification, are permitted provided that the following conditions
141.1Snonaka * are met:
151.1Snonaka * 1. Redistributions of source code must retain the above copyright
161.1Snonaka *    notice, this list of conditions and the following disclaimer.
171.1Snonaka * 2. Redistributions in binary form must reproduce the above copyright
181.1Snonaka *    notice, this list of conditions and the following disclaimer in the
191.1Snonaka *    documentation and/or other materials provided with the distribution.
201.1Snonaka * 3. All advertising materials mentioning features or use of this software
211.1Snonaka *    must display the following acknowledgement:
221.1Snonaka *	This product includes software developed by the NetBSD
231.1Snonaka *	Foundation, Inc. and its contributors.
241.1Snonaka * 4. Neither the name of The NetBSD Foundation nor the names of its
251.1Snonaka *    contributors may be used to endorse or promote products derived
261.1Snonaka *    from this software without specific prior written permission.
271.1Snonaka *
281.1Snonaka * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
291.1Snonaka * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
301.1Snonaka * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
311.1Snonaka * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
321.1Snonaka * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
331.1Snonaka * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
341.1Snonaka * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
351.1Snonaka * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
361.1Snonaka * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
371.1Snonaka * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
381.1Snonaka * POSSIBILITY OF SUCH DAMAGE.
391.1Snonaka */
401.1Snonaka
411.1Snonaka/*
421.1Snonaka * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
431.1Snonaka * Copyright (c) 1996 Jason R. Thorpe.  All rights reserved.
441.1Snonaka * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
451.1Snonaka *
461.1Snonaka * Redistribution and use in source and binary forms, with or without
471.1Snonaka * modification, are permitted provided that the following conditions
481.1Snonaka * are met:
491.1Snonaka * 1. Redistributions of source code must retain the above copyright
501.1Snonaka *    notice, this list of conditions and the following disclaimer.
511.1Snonaka * 2. Redistributions in binary form must reproduce the above copyright
521.1Snonaka *    notice, this list of conditions and the following disclaimer in the
531.1Snonaka *    documentation and/or other materials provided with the distribution.
541.1Snonaka * 3. All advertising materials mentioning features or use of this software
551.1Snonaka *    must display the following acknowledgement:
561.1Snonaka *      This product includes software developed by Christopher G. Demetriou
571.1Snonaka *	for the NetBSD Project.
581.1Snonaka * 4. The name of the author may not be used to endorse or promote products
591.1Snonaka *    derived from this software without specific prior written permission
601.1Snonaka *
611.1Snonaka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
621.1Snonaka * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
631.1Snonaka * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
641.1Snonaka * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
651.1Snonaka * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
661.1Snonaka * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
671.1Snonaka * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
681.1Snonaka * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
691.1Snonaka * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
701.1Snonaka * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
711.1Snonaka */
721.1Snonaka
731.1Snonaka/*
741.1Snonaka * Copyright (c) 1997 Per Fogelstrom.  All rights reserved.
751.1Snonaka * Copyright (c) 1996 Niklas Hallqvist.  All rights reserved.
761.1Snonaka *
771.1Snonaka * Redistribution and use in source and binary forms, with or without
781.1Snonaka * modification, are permitted provided that the following conditions
791.1Snonaka * are met:
801.1Snonaka * 1. Redistributions of source code must retain the above copyright
811.1Snonaka *    notice, this list of conditions and the following disclaimer.
821.1Snonaka * 2. Redistributions in binary form must reproduce the above copyright
831.1Snonaka *    notice, this list of conditions and the following disclaimer in the
841.1Snonaka *    documentation and/or other materials provided with the distribution.
851.1Snonaka * 3. All advertising materials mentioning features or use of this software
861.1Snonaka *    must display the following acknowledgement:
871.1Snonaka *      This product includes software developed by Christopher G. Demetriou
881.1Snonaka *	for the NetBSD Project.
891.1Snonaka * 4. The name of the author may not be used to endorse or promote products
901.1Snonaka *    derived from this software without specific prior written permission
911.1Snonaka *
921.1Snonaka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
931.1Snonaka * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
941.1Snonaka * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
951.1Snonaka * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
961.1Snonaka * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
971.1Snonaka * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
981.1Snonaka * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
991.1Snonaka * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1001.1Snonaka * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
1011.1Snonaka * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1021.1Snonaka */
1031.1Snonaka
1041.1Snonaka#ifndef _PREP_BUS_H_
1051.1Snonaka#define _PREP_BUS_H_
1061.1Snonaka
1071.1Snonaka#include <machine/pio.h>
1081.1Snonaka
1091.1Snonaka/*
1101.1Snonaka * Values for the Be bus space tag, not to be used directly by MI code.
1111.1Snonaka */
1121.1Snonaka#define	PREP_BUS_SPACE_IO	0x80000000	/* i/o space */
1131.1Snonaka#define PREP_BUS_SPACE_MEM	0xC0000000	/* mem space */
1141.1Snonaka
1151.1Snonaka/*
1161.1Snonaka * Address conversion as seen from a PCI master.
1171.1Snonaka */
1181.1Snonaka#define MPC105_DIRECT_MAPPED_SPACE	0x80000000
1191.1Snonaka#define PHYS_TO_PCI_MEM(x)	((x) | MPC105_DIRECT_MAPPED_SPACE)
1201.1Snonaka#define PCI_MEM_TO_PHYS(x)	((x) & ~MPC105_DIRECT_MAPPED_SPACE)
1211.1Snonaka
1221.1Snonaka/*
1231.1Snonaka * Bus access types.
1241.1Snonaka */
1251.1Snonakatypedef u_int32_t bus_addr_t;
1261.1Snonakatypedef u_int32_t bus_size_t;
1271.1Snonakatypedef	u_int32_t bus_space_handle_t;
1281.1Snonakatypedef	u_int32_t bus_space_tag_t;
1291.1Snonaka
1301.1Snonaka#define BUS_SPACE_MAP_CACHEABLE         0x01
1311.1Snonaka#define BUS_SPACE_MAP_LINEAR            0x02
1321.1Snonaka#define	BUS_SPACE_MAP_PREFETCHABLE	0x04
1331.1Snonaka
1341.1Snonaka#ifdef __STDC__
1351.1Snonaka#define CAT(a,b)	a##b
1361.1Snonaka#define CAT3(a,b,c)	a##b##c
1371.1Snonaka#else
1381.1Snonaka#define CAT(a,b)	a/**/b
1391.1Snonaka#define CAT3(a,b,c)	a/**/b/**/c
1401.1Snonaka#endif
1411.1Snonaka
1421.1Snonaka/*
1431.1Snonaka * Access methods for bus resources
1441.1Snonaka */
1451.1Snonaka
1461.1Snonaka#define	__BUS_SPACE_HAS_STREAM_METHODS
1471.1Snonaka
1481.1Snonaka/*
1491.1Snonaka *	int bus_space_map  __P((bus_space_tag_t t, bus_addr_t addr,
1501.1Snonaka *	    bus_size_t size, int flags, bus_space_handle_t *bshp));
1511.1Snonaka *
1521.1Snonaka * Map a region of bus space.
1531.1Snonaka */
1541.1Snonaka
1551.2Snonakaint	prep_memio_map __P((bus_space_tag_t t, bus_addr_t addr,
1561.2Snonaka	    bus_size_t size, int flags, bus_space_handle_t *bshp));
1571.2Snonaka
1581.2Snonaka#define bus_space_map(t, a, s, f, hp)					\
1591.2Snonaka    prep_memio_map((t), (a), (s), (f), (hp))
1601.1Snonaka
1611.1Snonaka/*
1621.1Snonaka *	int bus_space_unmap __P((bus_space_tag_t t,
1631.1Snonaka *	    bus_space_handle_t bsh, bus_size_t size));
1641.1Snonaka *
1651.1Snonaka * Unmap a region of bus space.
1661.1Snonaka */
1671.1Snonaka
1681.2Snonakavoid	prep_memio_unmap __P((bus_space_tag_t t, bus_space_handle_t bsh,
1691.2Snonaka	    bus_size_t size));
1701.2Snonaka
1711.2Snonaka#define bus_space_unmap(t, h, s)					\
1721.2Snonaka    prep_memio_unmap((t), (h), (s))
1731.1Snonaka
1741.1Snonaka/*
1751.1Snonaka *	int bus_space_subregion __P((bus_space_tag_t t,
1761.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
1771.1Snonaka *	    bus_space_handle_t *nbshp));
1781.1Snonaka *
1791.1Snonaka * Get a new handle for a subregion of an already-mapped area of bus space.
1801.1Snonaka */
1811.1Snonaka
1821.2Snonaka#define bus_space_subregion(t, h, o, s, hp)				\
1831.2Snonaka    ((*(hp) = (h) + (o)), 0)
1841.1Snonaka
1851.1Snonaka/*
1861.1Snonaka *	int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
1871.1Snonaka *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
1881.2Snonaka *	    bus_size_t boundary, int flags, bus_addr_t *bpap,
1891.1Snonaka *	    bus_space_handle_t *bshp));
1901.1Snonaka *
1911.1Snonaka * Allocate a region of bus space.
1921.1Snonaka */
1931.1Snonaka
1941.2Snonakaint	prep_memio_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
1951.2Snonaka	    bus_addr_t rend, bus_size_t size, bus_size_t align,
1961.2Snonaka	    bus_size_t boundary, int flags, bus_addr_t *bpap,
1971.2Snonaka	    bus_space_handle_t *bshp));
1981.2Snonaka
1991.2Snonaka#define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)			\
2001.2Snonaka    prep_memio_alloc((t), (rs), (re), (s), (a), (b), (f), (ap), (hp))
2011.1Snonaka
2021.1Snonaka/*
2031.1Snonaka *	int bus_space_free __P((bus_space_tag_t t,
2041.1Snonaka *	    bus_space_handle_t bsh, bus_size_t size));
2051.1Snonaka *
2061.1Snonaka * Free a region of bus space.
2071.1Snonaka */
2081.1Snonaka
2091.2Snonakavoid	prep_memio_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
2101.2Snonaka	    bus_size_t size));
2111.2Snonaka
2121.2Snonaka#define	bus_space_free(t, h, s)						\
2131.2Snonaka    prep_memio_free((t), (h), (s))
2141.1Snonaka
2151.1Snonaka/*
2161.1Snonaka *	u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
2171.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset));
2181.1Snonaka *
2191.1Snonaka * Read a 1, 2, 4, or 8 byte quantity from bus space
2201.1Snonaka * described by tag/handle/offset.
2211.1Snonaka */
2221.1Snonaka
2231.1Snonaka#define bus_space_read(n,m)						      \
2241.1Snonakastatic __inline CAT3(u_int,m,_t)					      \
2251.1SnonakaCAT(bus_space_read_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,	      \
2261.1Snonaka     bus_size_t offset)							      \
2271.1Snonaka{									      \
2281.1Snonaka	return CAT3(in,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)));  \
2291.1Snonaka}
2301.1Snonaka
2311.1Snonakabus_space_read(1,8)
2321.1Snonakabus_space_read(2,16)
2331.1Snonakabus_space_read(4,32)
2341.1Snonaka#define	bus_space_read_8	!!! bus_space_read_8 unimplemented !!!
2351.1Snonaka
2361.1Snonaka/*
2371.1Snonaka *	u_intN_t bus_space_read_stream_N __P((bus_space_tag_t tag,
2381.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset));
2391.1Snonaka *
2401.1Snonaka * Read a 2, 4, or 8 byte stream quantity from bus space
2411.1Snonaka * described by tag/handle/offset.
2421.1Snonaka */
2431.1Snonaka
2441.1Snonaka#define bus_space_read_stream(n,m)					      \
2451.1Snonakastatic __inline CAT3(u_int,m,_t)					      \
2461.1SnonakaCAT(bus_space_read_stream_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,    \
2471.1Snonaka     bus_size_t offset)							      \
2481.1Snonaka{									      \
2491.1Snonaka	return CAT(in,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)));  \
2501.1Snonaka}
2511.1Snonaka
2521.1Snonakabus_space_read_stream(2,16)
2531.1Snonakabus_space_read_stream(4,32)
2541.1Snonaka#define	bus_space_read_stream_8	!!! bus_space_read_stream_8 unimplemented !!!
2551.1Snonaka
2561.1Snonaka/*
2571.1Snonaka *	void bus_space_read_multi_N __P((bus_space_tag_t tag,
2581.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
2591.1Snonaka *	    u_intN_t *addr, size_t count));
2601.1Snonaka *
2611.1Snonaka * Read `count' 1, 2, 4, or 8 byte quantities from bus space
2621.1Snonaka * described by tag/handle/offset and copy into buffer provided.
2631.1Snonaka */
2641.1Snonaka
2651.1Snonaka#define bus_space_read_multi(n,m)					      \
2661.1Snonakastatic __inline void							      \
2671.1SnonakaCAT(bus_space_read_multi_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,     \
2681.1Snonaka     bus_size_t offset, CAT3(u_int,m,_t) *addr, size_t count)		      \
2691.1Snonaka{									      \
2701.1Snonaka	CAT3(ins,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)),	      \
2711.1Snonaka	    (CAT3(u_int,m,_t) *)addr, (size_t)count);			      \
2721.1Snonaka}
2731.1Snonaka
2741.1Snonakabus_space_read_multi(1,8)
2751.1Snonakabus_space_read_multi(2,16)
2761.1Snonakabus_space_read_multi(4,32)
2771.1Snonaka#define	bus_space_read_multi_8	!!! bus_space_read_multi_8 not implemented !!!
2781.1Snonaka
2791.1Snonaka/*
2801.1Snonaka *	void bus_space_read_multi_stream_N __P((bus_space_tag_t tag,
2811.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
2821.1Snonaka *	    u_intN_t *addr, size_t count));
2831.1Snonaka *
2841.1Snonaka * Read `count' 2, 4, or 8 byte stream quantities from bus space
2851.1Snonaka * described by tag/handle/offset and copy into buffer provided.
2861.1Snonaka */
2871.1Snonaka
2881.1Snonaka#define bus_space_read_multi_stream(n,m)				      \
2891.1Snonakastatic __inline void							      \
2901.1SnonakaCAT(bus_space_read_multi_stream_,n)(bus_space_tag_t tag,		      \
2911.1Snonaka     bus_space_handle_t bsh,						      \
2921.1Snonaka     bus_size_t offset, CAT3(u_int,m,_t) *addr, size_t count)		      \
2931.1Snonaka{									      \
2941.1Snonaka	CAT(ins,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)),	      \
2951.1Snonaka	    (CAT3(u_int,m,_t) *)addr, (size_t)count);			      \
2961.1Snonaka}
2971.1Snonaka
2981.1Snonakabus_space_read_multi_stream(2,16)
2991.1Snonakabus_space_read_multi_stream(4,32)
3001.1Snonaka#define	bus_space_read_multi_stream_8					      \
3011.1Snonaka	!!! bus_space_read_multi_stream_8 not implemented !!!
3021.1Snonaka
3031.1Snonaka/*
3041.1Snonaka *	void bus_space_write_N __P((bus_space_tag_t tag,
3051.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
3061.1Snonaka *	    u_intN_t value));
3071.1Snonaka *
3081.1Snonaka * Write the 1, 2, 4, or 8 byte value `value' to bus space
3091.1Snonaka * described by tag/handle/offset.
3101.1Snonaka */
3111.1Snonaka
3121.1Snonaka#define bus_space_write(n,m)						      \
3131.1Snonakastatic __inline void							      \
3141.1SnonakaCAT(bus_space_write_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,	      \
3151.1Snonaka     bus_size_t offset, CAT3(u_int,m,_t) x)				      \
3161.1Snonaka{									      \
3171.1Snonaka	CAT3(out,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), x);     \
3181.1Snonaka}
3191.1Snonaka
3201.1Snonakabus_space_write(1,8)
3211.1Snonakabus_space_write(2,16)
3221.1Snonakabus_space_write(4,32)
3231.1Snonaka#define	bus_space_write_8	!!! bus_space_write_8 unimplemented !!!
3241.1Snonaka
3251.1Snonaka/*
3261.1Snonaka *	void bus_space_write_stream_N __P((bus_space_tag_t tag,
3271.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
3281.1Snonaka *	    u_intN_t value));
3291.1Snonaka *
3301.1Snonaka * Write the 2, 4, or 8 byte stream value `value' to bus space
3311.1Snonaka * described by tag/handle/offset.
3321.1Snonaka */
3331.1Snonaka
3341.1Snonaka#define bus_space_write_stream(n,m)					      \
3351.1Snonakastatic __inline void							      \
3361.1SnonakaCAT(bus_space_write_stream_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,   \
3371.1Snonaka     bus_size_t offset, CAT3(u_int,m,_t) x)				      \
3381.1Snonaka{									      \
3391.1Snonaka	CAT(out,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)), x);     \
3401.1Snonaka}
3411.1Snonaka
3421.1Snonakabus_space_write_stream(2,16)
3431.1Snonakabus_space_write_stream(4,32)
3441.1Snonaka#define	bus_space_write_stream_8 !!! bus_space_write_stream_8 unimplemented !!!
3451.1Snonaka
3461.1Snonaka/*
3471.1Snonaka *	void bus_space_write_multi_N __P((bus_space_tag_t tag,
3481.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
3491.1Snonaka *	    const u_intN_t *addr, size_t count));
3501.1Snonaka *
3511.1Snonaka * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
3521.1Snonaka * provided to bus space described by tag/handle/offset.
3531.1Snonaka */
3541.1Snonaka
3551.1Snonaka#define bus_space_write_multi(n,m)					      \
3561.1Snonakastatic __inline void							      \
3571.1SnonakaCAT(bus_space_write_multi_,n)(bus_space_tag_t tag, bus_space_handle_t bsh,    \
3581.1Snonaka     bus_size_t offset, const CAT3(u_int,m,_t) *addr, size_t count)	      \
3591.1Snonaka{									      \
3601.1Snonaka	CAT3(outs,m,rb)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)),	      \
3611.1Snonaka	    (CAT3(u_int,m,_t) *)addr, (size_t)count);			      \
3621.1Snonaka}
3631.1Snonaka
3641.1Snonakabus_space_write_multi(1,8)
3651.1Snonakabus_space_write_multi(2,16)
3661.1Snonakabus_space_write_multi(4,32)
3671.1Snonaka#define	bus_space_write_multi_8	!!! bus_space_write_multi_8 not implemented !!!
3681.1Snonaka
3691.1Snonaka/*
3701.1Snonaka *	void bus_space_write_multi_stream_N __P((bus_space_tag_t tag,
3711.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
3721.1Snonaka *	    const u_intN_t *addr, size_t count));
3731.1Snonaka *
3741.1Snonaka * Write `count' 2, 4, or 8 byte stream quantities from the buffer
3751.1Snonaka * provided to bus space described by tag/handle/offset.
3761.1Snonaka */
3771.1Snonaka
3781.1Snonaka#define bus_space_write_multi_stream(n,m)				      \
3791.1Snonakastatic __inline void							      \
3801.1SnonakaCAT(bus_space_write_multi_stream_,n)(bus_space_tag_t tag,		      \
3811.1Snonaka     bus_space_handle_t bsh,						      \
3821.1Snonaka     bus_size_t offset, const CAT3(u_int,m,_t) *addr, size_t count)	      \
3831.1Snonaka{									      \
3841.1Snonaka	CAT(outs,m)((volatile CAT3(u_int,m,_t) *)(bsh + (offset)),	      \
3851.1Snonaka	    (CAT3(u_int,m,_t) *)addr, (size_t)count);			      \
3861.1Snonaka}
3871.1Snonaka
3881.1Snonakabus_space_write_multi_stream(2,16)
3891.1Snonakabus_space_write_multi_stream(4,32)
3901.1Snonaka#define	bus_space_write_multi_stream_8					      \
3911.1Snonaka	!!! bus_space_write_multi_stream_8 not implemented !!!
3921.1Snonaka
3931.1Snonaka/*
3941.1Snonaka *	void bus_space_read_region_N __P((bus_space_tag_t tag,
3951.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
3961.1Snonaka *	    u_intN_t *addr, size_t count));
3971.1Snonaka *
3981.1Snonaka * Read `count' 1, 2, 4, or 8 byte quantities from bus space
3991.1Snonaka * described by tag/handle and starting at `offset' and copy into
4001.1Snonaka * buffer provided.
4011.1Snonaka */
4021.1Snonakastatic __inline void bus_space_read_region_1 __P((bus_space_tag_t,
4031.1Snonaka	bus_space_handle_t, bus_size_t, u_int8_t *, size_t));
4041.1Snonakastatic __inline void bus_space_read_region_2 __P((bus_space_tag_t,
4051.1Snonaka	bus_space_handle_t, bus_size_t, u_int16_t *, size_t));
4061.1Snonakastatic __inline void bus_space_read_region_4 __P((bus_space_tag_t,
4071.1Snonaka	bus_space_handle_t, bus_size_t, u_int32_t *, size_t));
4081.1Snonaka
4091.1Snonakastatic __inline void
4101.1Snonakabus_space_read_region_1(tag, bsh, offset, addr, count)
4111.1Snonaka	bus_space_tag_t tag;
4121.1Snonaka	bus_space_handle_t bsh;
4131.1Snonaka	bus_size_t offset;
4141.1Snonaka	u_int8_t *addr;
4151.1Snonaka	size_t count;
4161.1Snonaka{
4171.1Snonaka	volatile u_int8_t *s;
4181.1Snonaka
4191.1Snonaka	s = (volatile u_int8_t *)(bsh + offset);
4201.1Snonaka	while (count--)
4211.1Snonaka		*addr++ = *s++;
4221.1Snonaka	__asm__ volatile("eieio; sync");
4231.1Snonaka}
4241.1Snonaka
4251.1Snonakastatic __inline void
4261.1Snonakabus_space_read_region_2(tag, bsh, offset, addr, count)
4271.1Snonaka	bus_space_tag_t tag;
4281.1Snonaka	bus_space_handle_t bsh;
4291.1Snonaka	bus_size_t offset;
4301.1Snonaka	u_int16_t *addr;
4311.1Snonaka	size_t count;
4321.1Snonaka{
4331.1Snonaka	volatile u_int16_t *s;
4341.1Snonaka
4351.1Snonaka	s = (volatile u_int16_t *)(bsh + offset);
4361.1Snonaka	while (count--)
4371.1Snonaka		__asm__ volatile("lhbrx %0, 0, %1" :
4381.1Snonaka			"=r"(*addr++) : "r"(s++));
4391.1Snonaka	__asm__ volatile("eieio; sync");
4401.1Snonaka}
4411.1Snonaka
4421.1Snonakastatic __inline void
4431.1Snonakabus_space_read_region_4(tag, bsh, offset, addr, count)
4441.1Snonaka	bus_space_tag_t tag;
4451.1Snonaka	bus_space_handle_t bsh;
4461.1Snonaka	bus_size_t offset;
4471.1Snonaka	u_int32_t *addr;
4481.1Snonaka	size_t count;
4491.1Snonaka{
4501.1Snonaka	volatile u_int32_t *s;
4511.1Snonaka
4521.1Snonaka	s = (volatile u_int32_t *)(bsh + offset);
4531.1Snonaka	while (count--)
4541.1Snonaka		__asm__ volatile("lwbrx %0, 0, %1" :
4551.1Snonaka			"=r"(*addr++) : "r"(s++));
4561.1Snonaka	__asm__ volatile("eieio; sync");
4571.1Snonaka}
4581.1Snonaka
4591.1Snonaka#define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
4601.1Snonaka
4611.1Snonaka/*
4621.1Snonaka *	void bus_space_read_region_stream_N __P((bus_space_tag_t tag,
4631.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
4641.1Snonaka *	    u_intN_t *addr, size_t count));
4651.1Snonaka *
4661.1Snonaka * Read `count' 2, 4, or 8 byte stream quantities from bus space
4671.1Snonaka * described by tag/handle and starting at `offset' and copy into
4681.1Snonaka * buffer provided.
4691.1Snonaka */
4701.1Snonakastatic __inline void bus_space_read_region_stream_2 __P((bus_space_tag_t,
4711.1Snonaka	bus_space_handle_t, bus_size_t, u_int16_t *, size_t));
4721.1Snonakastatic __inline void bus_space_read_region_stream_4 __P((bus_space_tag_t,
4731.1Snonaka	bus_space_handle_t, bus_size_t, u_int32_t *, size_t));
4741.1Snonaka
4751.1Snonakastatic __inline void
4761.1Snonakabus_space_read_region_stream_2(tag, bsh, offset, addr, count)
4771.1Snonaka	bus_space_tag_t tag;
4781.1Snonaka	bus_space_handle_t bsh;
4791.1Snonaka	bus_size_t offset;
4801.1Snonaka	u_int16_t *addr;
4811.1Snonaka	size_t count;
4821.1Snonaka{
4831.1Snonaka	volatile u_int16_t *s;
4841.1Snonaka
4851.1Snonaka	s = (volatile u_int16_t *)(bsh + offset);
4861.1Snonaka	while (count--)
4871.1Snonaka		*addr++ = *s++;
4881.1Snonaka	__asm__ volatile("eieio; sync");
4891.1Snonaka}
4901.1Snonaka
4911.1Snonakastatic __inline void
4921.1Snonakabus_space_read_region_stream_4(tag, bsh, offset, addr, count)
4931.1Snonaka	bus_space_tag_t tag;
4941.1Snonaka	bus_space_handle_t bsh;
4951.1Snonaka	bus_size_t offset;
4961.1Snonaka	u_int32_t *addr;
4971.1Snonaka	size_t count;
4981.1Snonaka{
4991.1Snonaka	volatile u_int32_t *s;
5001.1Snonaka
5011.1Snonaka	s = (volatile u_int32_t *)(bsh + offset);
5021.1Snonaka	while (count--)
5031.1Snonaka		*addr++ = *s++;
5041.1Snonaka	__asm__ volatile("eieio; sync");
5051.1Snonaka}
5061.1Snonaka
5071.1Snonaka#define	bus_space_read_region_stream_8					      \
5081.1Snonaka	!!! bus_space_read_region_stream_8 unimplemented !!!
5091.1Snonaka
5101.1Snonaka/*
5111.1Snonaka *	void bus_space_write_region_N __P((bus_space_tag_t tag,
5121.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
5131.1Snonaka *	    const u_intN_t *addr, size_t count));
5141.1Snonaka *
5151.1Snonaka * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
5161.1Snonaka * to bus space described by tag/handle starting at `offset'.
5171.1Snonaka */
5181.1Snonakastatic __inline void bus_space_write_region_1 __P((bus_space_tag_t,
5191.1Snonaka	bus_space_handle_t, bus_size_t, const u_int8_t *, size_t));
5201.1Snonakastatic __inline void bus_space_write_region_2 __P((bus_space_tag_t,
5211.1Snonaka	bus_space_handle_t, bus_size_t, const u_int16_t *, size_t));
5221.1Snonakastatic __inline void bus_space_write_region_4 __P((bus_space_tag_t,
5231.1Snonaka	bus_space_handle_t, bus_size_t, const u_int32_t *, size_t));
5241.1Snonaka
5251.1Snonakastatic __inline void
5261.1Snonakabus_space_write_region_1(tag, bsh, offset, addr, count)
5271.1Snonaka	bus_space_tag_t tag;
5281.1Snonaka	bus_space_handle_t bsh;
5291.1Snonaka	bus_size_t offset;
5301.1Snonaka	const u_int8_t *addr;
5311.1Snonaka	size_t count;
5321.1Snonaka{
5331.1Snonaka	volatile u_int8_t *d;
5341.1Snonaka
5351.1Snonaka	d = (volatile u_int8_t *)(bsh + offset);
5361.1Snonaka	while (count--)
5371.1Snonaka		*d++ = *addr++;
5381.1Snonaka	__asm__ volatile("eieio; sync");
5391.1Snonaka}
5401.1Snonaka
5411.1Snonakastatic __inline void
5421.1Snonakabus_space_write_region_2(tag, bsh, offset, addr, count)
5431.1Snonaka	bus_space_tag_t tag;
5441.1Snonaka	bus_space_handle_t bsh;
5451.1Snonaka	bus_size_t offset;
5461.1Snonaka	const u_int16_t *addr;
5471.1Snonaka	size_t count;
5481.1Snonaka{
5491.1Snonaka	volatile u_int16_t *d;
5501.1Snonaka
5511.1Snonaka	d = (volatile u_int16_t *)(bsh + offset);
5521.1Snonaka	while (count--)
5531.1Snonaka		__asm__ volatile("sthbrx %0, 0, %1" ::
5541.1Snonaka			"r"(*addr++), "r"(d++));
5551.1Snonaka	__asm__ volatile("eieio; sync");
5561.1Snonaka}
5571.1Snonaka
5581.1Snonakastatic __inline void
5591.1Snonakabus_space_write_region_4(tag, bsh, offset, addr, count)
5601.1Snonaka	bus_space_tag_t tag;
5611.1Snonaka	bus_space_handle_t bsh;
5621.1Snonaka	bus_size_t offset;
5631.1Snonaka	const u_int32_t *addr;
5641.1Snonaka	size_t count;
5651.1Snonaka{
5661.1Snonaka	volatile u_int32_t *d;
5671.1Snonaka
5681.1Snonaka	d = (volatile u_int32_t *)(bsh + offset);
5691.1Snonaka	while (count--)
5701.1Snonaka		__asm__ volatile("stwbrx %0, 0, %1" ::
5711.1Snonaka			"r"(*addr++), "r"(d++));
5721.1Snonaka	__asm__ volatile("eieio; sync");
5731.1Snonaka}
5741.1Snonaka
5751.1Snonaka#define	bus_space_write_region_8 !!! bus_space_write_region_8 unimplemented !!!
5761.1Snonaka
5771.1Snonaka/*
5781.1Snonaka *	void bus_space_write_region_stream_N __P((bus_space_tag_t tag,
5791.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
5801.1Snonaka *	    const u_intN_t *addr, size_t count));
5811.1Snonaka *
5821.1Snonaka * Write `count' 2, 4, or 8 byte stream quantities from the buffer provided
5831.1Snonaka * to bus space described by tag/handle starting at `offset'.
5841.1Snonaka */
5851.1Snonakastatic __inline void bus_space_write_region_stream_2 __P((bus_space_tag_t,
5861.1Snonaka	bus_space_handle_t, bus_size_t, const u_int16_t *, size_t));
5871.1Snonakastatic __inline void bus_space_write_region_stream_4 __P((bus_space_tag_t,
5881.1Snonaka	bus_space_handle_t, bus_size_t, const u_int32_t *, size_t));
5891.1Snonaka
5901.1Snonakastatic __inline void
5911.1Snonakabus_space_write_region_stream_2(tag, bsh, offset, addr, count)
5921.1Snonaka	bus_space_tag_t tag;
5931.1Snonaka	bus_space_handle_t bsh;
5941.1Snonaka	bus_size_t offset;
5951.1Snonaka	const u_int16_t *addr;
5961.1Snonaka	size_t count;
5971.1Snonaka{
5981.1Snonaka	volatile u_int16_t *d;
5991.1Snonaka
6001.1Snonaka	d = (volatile u_int16_t *)(bsh + offset);
6011.1Snonaka	while (count--)
6021.1Snonaka		*d++ = *addr++;
6031.1Snonaka	__asm__ volatile("eieio; sync");
6041.1Snonaka}
6051.1Snonaka
6061.1Snonakastatic __inline void
6071.1Snonakabus_space_write_region_stream_4(tag, bsh, offset, addr, count)
6081.1Snonaka	bus_space_tag_t tag;
6091.1Snonaka	bus_space_handle_t bsh;
6101.1Snonaka	bus_size_t offset;
6111.1Snonaka	const u_int32_t *addr;
6121.1Snonaka	size_t count;
6131.1Snonaka{
6141.1Snonaka	volatile u_int32_t *d;
6151.1Snonaka
6161.1Snonaka	d = (volatile u_int32_t *)(bsh + offset);
6171.1Snonaka	while (count--)
6181.1Snonaka		*d++ = *addr++;
6191.1Snonaka	__asm__ volatile("eieio; sync");
6201.1Snonaka}
6211.1Snonaka
6221.1Snonaka#define	bus_space_write_region_stream_8					      \
6231.1Snonaka	 !!! bus_space_write_region_stream_8 unimplemented !!!
6241.1Snonaka
6251.1Snonaka/*
6261.1Snonaka *	void bus_space_set_multi_N __P((bus_space_tag_t tag,
6271.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
6281.1Snonaka *	    size_t count));
6291.1Snonaka *
6301.1Snonaka * Write the 1, 2, 4, or 8 byte value `val' to bus space described
6311.1Snonaka * by tag/handle/offset `count' times.
6321.1Snonaka */
6331.1Snonakastatic __inline void bus_space_set_multi_1 __P((bus_space_tag_t,
6341.1Snonaka	bus_space_handle_t, bus_size_t, u_int8_t, size_t));
6351.1Snonakastatic __inline void bus_space_set_multi_2 __P((bus_space_tag_t,
6361.1Snonaka	bus_space_handle_t, bus_size_t, u_int16_t, size_t));
6371.1Snonakastatic __inline void bus_space_set_multi_4 __P((bus_space_tag_t,
6381.1Snonaka	bus_space_handle_t, bus_size_t, u_int32_t, size_t));
6391.1Snonaka
6401.1Snonakastatic __inline void
6411.1Snonakabus_space_set_multi_1(tag, bsh, offset, val, count)
6421.1Snonaka	bus_space_tag_t tag;
6431.1Snonaka	bus_space_handle_t bsh;
6441.1Snonaka	bus_size_t offset;
6451.1Snonaka	u_int8_t val;
6461.1Snonaka	size_t count;
6471.1Snonaka{
6481.1Snonaka	volatile u_int8_t *d;
6491.1Snonaka
6501.1Snonaka	d = (volatile u_int8_t *)(bsh + offset);
6511.1Snonaka	while (count--)
6521.1Snonaka		*d = val;
6531.1Snonaka	__asm__ volatile("eieio; sync");
6541.1Snonaka}
6551.1Snonaka
6561.1Snonakastatic __inline void
6571.1Snonakabus_space_set_multi_2(tag, bsh, offset, val, count)
6581.1Snonaka	bus_space_tag_t tag;
6591.1Snonaka	bus_space_handle_t bsh;
6601.1Snonaka	bus_size_t offset;
6611.1Snonaka	u_int16_t val;
6621.1Snonaka	size_t count;
6631.1Snonaka{
6641.1Snonaka	volatile u_int16_t *d;
6651.1Snonaka
6661.1Snonaka	d = (volatile u_int16_t *)(bsh + offset);
6671.1Snonaka	while (count--)
6681.1Snonaka		__asm__ volatile("sthbrx %0, 0, %1" ::
6691.1Snonaka			"r"(val), "r"(d));
6701.1Snonaka	__asm__ volatile("eieio; sync");
6711.1Snonaka}
6721.1Snonaka
6731.1Snonakastatic __inline void
6741.1Snonakabus_space_set_multi_4(tag, bsh, offset, val, count)
6751.1Snonaka	bus_space_tag_t tag;
6761.1Snonaka	bus_space_handle_t bsh;
6771.1Snonaka	bus_size_t offset;
6781.1Snonaka	u_int32_t val;
6791.1Snonaka	size_t count;
6801.1Snonaka{
6811.1Snonaka	volatile u_int32_t *d;
6821.1Snonaka
6831.1Snonaka	d = (volatile u_int32_t *)(bsh + offset);
6841.1Snonaka	while (count--)
6851.1Snonaka		__asm__ volatile("stwbrx %0, 0, %1" ::
6861.1Snonaka			"r"(val), "r"(d));
6871.1Snonaka	__asm__ volatile("eieio; sync");
6881.1Snonaka}
6891.1Snonaka
6901.1Snonaka#define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
6911.1Snonaka
6921.1Snonaka/*
6931.1Snonaka *	void bus_space_set_multi_stream_N __P((bus_space_tag_t tag,
6941.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
6951.1Snonaka *	    size_t count));
6961.1Snonaka *
6971.1Snonaka * Write the 2, 4, or 8 byte stream value `val' to bus space described
6981.1Snonaka * by tag/handle/offset `count' times.
6991.1Snonaka */
7001.1Snonakastatic __inline void bus_space_set_multi_stream_2 __P((bus_space_tag_t,
7011.1Snonaka	bus_space_handle_t, bus_size_t, u_int16_t, size_t));
7021.1Snonakastatic __inline void bus_space_set_multi_stream_4 __P((bus_space_tag_t,
7031.1Snonaka	bus_space_handle_t, bus_size_t, u_int32_t, size_t));
7041.1Snonaka
7051.1Snonakastatic __inline void
7061.1Snonakabus_space_set_multi_stream_2(tag, bsh, offset, val, count)
7071.1Snonaka	bus_space_tag_t tag;
7081.1Snonaka	bus_space_handle_t bsh;
7091.1Snonaka	bus_size_t offset;
7101.1Snonaka	u_int16_t val;
7111.1Snonaka	size_t count;
7121.1Snonaka{
7131.1Snonaka	volatile u_int16_t *d;
7141.1Snonaka
7151.1Snonaka	d = (volatile u_int16_t *)(bsh + offset);
7161.1Snonaka	while (count--)
7171.1Snonaka		*d = val;
7181.1Snonaka	__asm__ volatile("eieio; sync");
7191.1Snonaka}
7201.1Snonaka
7211.1Snonakastatic __inline void
7221.1Snonakabus_space_set_multi_stream_4(tag, bsh, offset, val, count)
7231.1Snonaka	bus_space_tag_t tag;
7241.1Snonaka	bus_space_handle_t bsh;
7251.1Snonaka	bus_size_t offset;
7261.1Snonaka	u_int32_t val;
7271.1Snonaka	size_t count;
7281.1Snonaka{
7291.1Snonaka	volatile u_int32_t *d;
7301.1Snonaka
7311.1Snonaka	d = (volatile u_int32_t *)(bsh + offset);
7321.1Snonaka	while (count--)
7331.1Snonaka		*d = val;
7341.1Snonaka	__asm__ volatile("eieio; sync");
7351.1Snonaka}
7361.1Snonaka
7371.1Snonaka#define	bus_space_set_multi_stream_8					      \
7381.1Snonaka	!!! bus_space_set_multi_stream_8 unimplemented !!!
7391.1Snonaka
7401.1Snonaka/*
7411.1Snonaka *	void bus_space_set_region_N __P((bus_space_tag_t tag,
7421.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
7431.1Snonaka *	    size_t count));
7441.1Snonaka *
7451.1Snonaka * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
7461.1Snonaka * by tag/handle starting at `offset'.
7471.1Snonaka */
7481.1Snonakastatic __inline void bus_space_set_region_1 __P((bus_space_tag_t,
7491.1Snonaka	bus_space_handle_t, bus_size_t, u_int8_t, size_t));
7501.1Snonakastatic __inline void bus_space_set_region_2 __P((bus_space_tag_t,
7511.1Snonaka	bus_space_handle_t, bus_size_t, u_int16_t, size_t));
7521.1Snonakastatic __inline void bus_space_set_region_4 __P((bus_space_tag_t,
7531.1Snonaka	bus_space_handle_t, bus_size_t, u_int32_t, size_t));
7541.1Snonaka
7551.1Snonakastatic __inline void
7561.1Snonakabus_space_set_region_1(tag, bsh, offset, val, count)
7571.1Snonaka	bus_space_tag_t tag;
7581.1Snonaka	bus_space_handle_t bsh;
7591.1Snonaka	bus_size_t offset;
7601.1Snonaka	u_int8_t val;
7611.1Snonaka	size_t count;
7621.1Snonaka{
7631.1Snonaka	volatile u_int8_t *d;
7641.1Snonaka
7651.1Snonaka	d = (volatile u_int8_t *)(bsh + offset);
7661.1Snonaka	while (count--)
7671.1Snonaka		*d++ = val;
7681.1Snonaka	__asm__ volatile("eieio; sync");
7691.1Snonaka}
7701.1Snonaka
7711.1Snonakastatic __inline void
7721.1Snonakabus_space_set_region_2(tag, bsh, offset, val, count)
7731.1Snonaka	bus_space_tag_t tag;
7741.1Snonaka	bus_space_handle_t bsh;
7751.1Snonaka	bus_size_t offset;
7761.1Snonaka	u_int16_t val;
7771.1Snonaka	size_t count;
7781.1Snonaka{
7791.1Snonaka	volatile u_int16_t *d;
7801.1Snonaka
7811.1Snonaka	d = (volatile u_int16_t *)(bsh + offset);
7821.1Snonaka	while (count--)
7831.1Snonaka		__asm__ volatile("sthbrx %0, 0, %1" ::
7841.1Snonaka			"r"(val), "r"(d++));
7851.1Snonaka	__asm__ volatile("eieio; sync");
7861.1Snonaka}
7871.1Snonaka
7881.1Snonakastatic __inline void
7891.1Snonakabus_space_set_region_4(tag, bsh, offset, val, count)
7901.1Snonaka	bus_space_tag_t tag;
7911.1Snonaka	bus_space_handle_t bsh;
7921.1Snonaka	bus_size_t offset;
7931.1Snonaka	u_int32_t val;
7941.1Snonaka	size_t count;
7951.1Snonaka{
7961.1Snonaka	volatile u_int32_t *d;
7971.1Snonaka
7981.1Snonaka	d = (volatile u_int32_t *)(bsh + offset);
7991.1Snonaka	while (count--)
8001.1Snonaka		__asm__ volatile("stwbrx %0, 0, %1" ::
8011.1Snonaka			"r"(val), "r"(d++));
8021.1Snonaka	__asm__ volatile("eieio; sync");
8031.1Snonaka}
8041.1Snonaka
8051.1Snonaka#define	bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
8061.1Snonaka
8071.1Snonaka/*
8081.1Snonaka *	void bus_space_set_region_stream_N __P((bus_space_tag_t tag,
8091.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
8101.1Snonaka *	    size_t count));
8111.1Snonaka *
8121.1Snonaka * Write `count' 2, 4, or 8 byte stream value `val' to bus space described
8131.1Snonaka * by tag/handle starting at `offset'.
8141.1Snonaka */
8151.1Snonakastatic __inline void bus_space_set_region_stream_2 __P((bus_space_tag_t,
8161.1Snonaka	bus_space_handle_t, bus_size_t, u_int16_t, size_t));
8171.1Snonakastatic __inline void bus_space_set_region_stream_4 __P((bus_space_tag_t,
8181.1Snonaka	bus_space_handle_t, bus_size_t, u_int32_t, size_t));
8191.1Snonaka
8201.1Snonaka
8211.1Snonakastatic __inline void
8221.1Snonakabus_space_set_region_stream_2(tag, bsh, offset, val, count)
8231.1Snonaka	bus_space_tag_t tag;
8241.1Snonaka	bus_space_handle_t bsh;
8251.1Snonaka	bus_size_t offset;
8261.1Snonaka	u_int16_t val;
8271.1Snonaka	size_t count;
8281.1Snonaka{
8291.1Snonaka	volatile u_int16_t *d;
8301.1Snonaka
8311.1Snonaka	d = (volatile u_int16_t *)(bsh + offset);
8321.1Snonaka	while (count--)
8331.1Snonaka		*d++ = val;
8341.1Snonaka	__asm__ volatile("eieio; sync");
8351.1Snonaka}
8361.1Snonaka
8371.1Snonakastatic __inline void
8381.1Snonakabus_space_set_region_stream_4(tag, bsh, offset, val, count)
8391.1Snonaka	bus_space_tag_t tag;
8401.1Snonaka	bus_space_handle_t bsh;
8411.1Snonaka	bus_size_t offset;
8421.1Snonaka	u_int32_t val;
8431.1Snonaka	size_t count;
8441.1Snonaka{
8451.1Snonaka	volatile u_int32_t *d;
8461.1Snonaka
8471.1Snonaka	d = (volatile u_int32_t *)(bsh + offset);
8481.1Snonaka	while (count--)
8491.1Snonaka		*d++ = val;
8501.1Snonaka	__asm__ volatile("eieio; sync");
8511.1Snonaka}
8521.1Snonaka
8531.1Snonaka#define	bus_space_set_region_stream_8					      \
8541.1Snonaka	!!! bus_space_set_region_stream_8 unimplemented !!!
8551.1Snonaka
8561.1Snonaka/*
8571.1Snonaka *	void bus_space_copy_region_N __P((bus_space_tag_t tag,
8581.1Snonaka *	    bus_space_handle_t bsh1, bus_size_t off1,
8591.1Snonaka *	    bus_space_handle_t bsh2, bus_size_t off2,
8601.1Snonaka *	    size_t count));
8611.1Snonaka *
8621.1Snonaka * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
8631.1Snonaka * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
8641.1Snonaka */
8651.1Snonaka
8661.1Snonakastatic __inline void bus_space_copy_region_1 __P((bus_space_tag_t,
8671.1Snonaka	bus_space_handle_t, bus_size_t, bus_space_handle_t,
8681.1Snonaka	bus_size_t, size_t));
8691.1Snonakastatic __inline void bus_space_copy_region_2 __P((bus_space_tag_t,
8701.1Snonaka	bus_space_handle_t, bus_size_t, bus_space_handle_t,
8711.1Snonaka	bus_size_t, size_t));
8721.1Snonakastatic __inline void bus_space_copy_region_4 __P((bus_space_tag_t,
8731.1Snonaka	bus_space_handle_t, bus_size_t, bus_space_handle_t,
8741.1Snonaka	bus_size_t, size_t));
8751.1Snonaka
8761.1Snonakastatic __inline void
8771.1Snonakabus_space_copy_region_1(t, h1, o1, h2, o2, c)
8781.1Snonaka	bus_space_tag_t t;
8791.1Snonaka	bus_space_handle_t h1;
8801.1Snonaka	bus_size_t o1;
8811.1Snonaka	bus_space_handle_t h2;
8821.1Snonaka	bus_size_t o2;
8831.1Snonaka	size_t c;
8841.1Snonaka{
8851.1Snonaka	bus_addr_t addr1 = h1 + o1;
8861.1Snonaka	bus_addr_t addr2 = h2 + o2;
8871.1Snonaka
8881.1Snonaka	if (addr1 >= addr2) {
8891.1Snonaka		/* src after dest: copy forward */
8901.1Snonaka		for (; c != 0; c--, addr1++, addr2++)
8911.1Snonaka			*(volatile u_int8_t *)(addr2) =
8921.1Snonaka			    *(volatile u_int8_t *)(addr1);
8931.1Snonaka	} else {
8941.1Snonaka		/* dest after src: copy backwards */
8951.1Snonaka		for (addr1 += (c - 1), addr2 += (c - 1);
8961.1Snonaka		    c != 0; c--, addr1--, addr2--)
8971.1Snonaka			*(volatile u_int8_t *)(addr2) =
8981.1Snonaka			    *(volatile u_int8_t *)(addr1);
8991.1Snonaka	}
9001.1Snonaka}
9011.1Snonaka
9021.1Snonakastatic __inline void
9031.1Snonakabus_space_copy_region_2(t, h1, o1, h2, o2, c)
9041.1Snonaka	bus_space_tag_t t;
9051.1Snonaka	bus_space_handle_t h1;
9061.1Snonaka	bus_size_t o1;
9071.1Snonaka	bus_space_handle_t h2;
9081.1Snonaka	bus_size_t o2;
9091.1Snonaka	size_t c;
9101.1Snonaka{
9111.1Snonaka	bus_addr_t addr1 = h1 + o1;
9121.1Snonaka	bus_addr_t addr2 = h2 + o2;
9131.1Snonaka
9141.1Snonaka	if (addr1 >= addr2) {
9151.1Snonaka		/* src after dest: copy forward */
9161.1Snonaka		for (; c != 0; c--, addr1 += 2, addr2 += 2)
9171.1Snonaka			*(volatile u_int16_t *)(addr2) =
9181.1Snonaka			    *(volatile u_int16_t *)(addr1);
9191.1Snonaka	} else {
9201.1Snonaka		/* dest after src: copy backwards */
9211.1Snonaka		for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
9221.1Snonaka		    c != 0; c--, addr1 -= 2, addr2 -= 2)
9231.1Snonaka			*(volatile u_int16_t *)(addr2) =
9241.1Snonaka			    *(volatile u_int16_t *)(addr1);
9251.1Snonaka	}
9261.1Snonaka}
9271.1Snonaka
9281.1Snonakastatic __inline void
9291.1Snonakabus_space_copy_region_4(t, h1, o1, h2, o2, c)
9301.1Snonaka	bus_space_tag_t t;
9311.1Snonaka	bus_space_handle_t h1;
9321.1Snonaka	bus_size_t o1;
9331.1Snonaka	bus_space_handle_t h2;
9341.1Snonaka	bus_size_t o2;
9351.1Snonaka	size_t c;
9361.1Snonaka{
9371.1Snonaka	bus_addr_t addr1 = h1 + o1;
9381.1Snonaka	bus_addr_t addr2 = h2 + o2;
9391.1Snonaka
9401.1Snonaka	if (addr1 >= addr2) {
9411.1Snonaka		/* src after dest: copy forward */
9421.1Snonaka		for (; c != 0; c--, addr1 += 4, addr2 += 4)
9431.1Snonaka			*(volatile u_int32_t *)(addr2) =
9441.1Snonaka			    *(volatile u_int32_t *)(addr1);
9451.1Snonaka	} else {
9461.1Snonaka		/* dest after src: copy backwards */
9471.1Snonaka		for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
9481.1Snonaka		    c != 0; c--, addr1 -= 4, addr2 -= 4)
9491.1Snonaka			*(volatile u_int32_t *)(addr2) =
9501.1Snonaka			    *(volatile u_int32_t *)(addr1);
9511.1Snonaka	}
9521.1Snonaka}
9531.1Snonaka
9541.1Snonaka#define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
9551.1Snonaka
9561.1Snonaka/*
9571.1Snonaka * Bus read/write barrier methods.
9581.1Snonaka *
9591.1Snonaka *	void bus_space_barrier __P((bus_space_tag_t tag,
9601.1Snonaka *	    bus_space_handle_t bsh, bus_size_t offset,
9611.1Snonaka *	    bus_size_t len, int flags));
9621.1Snonaka *
9631.1Snonaka */
9641.1Snonaka#define	bus_space_barrier(t, h, o, l, f)	\
9651.1Snonaka	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
9661.1Snonaka#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
9671.1Snonaka#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
9681.1Snonaka
9691.1Snonaka#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
9701.1Snonaka
9711.1Snonaka/*
9721.1Snonaka * Bus DMA methods.
9731.1Snonaka */
9741.1Snonaka
9751.1Snonaka/*
9761.1Snonaka * Flags used in various bus DMA methods.
9771.1Snonaka */
9781.1Snonaka#define	BUS_DMA_WAITOK		0x00	/* safe to sleep (pseudo-flag) */
9791.1Snonaka#define	BUS_DMA_NOWAIT		0x01	/* not safe to sleep */
9801.1Snonaka#define	BUS_DMA_ALLOCNOW	0x02	/* perform resource allocation now */
9811.1Snonaka#define	BUS_DMA_COHERENT	0x04	/* hint: map memory DMA coherent */
9821.1Snonaka#define	BUS_DMA_BUS1		0x10	/* placeholders for bus functions... */
9831.1Snonaka#define	BUS_DMA_BUS2		0x20
9841.1Snonaka#define	BUS_DMA_BUS3		0x40
9851.1Snonaka#define	BUS_DMA_BUS4		0x80
9861.1Snonaka
9871.1Snonaka/* Forwards needed by prototypes below. */
9881.1Snonakastruct mbuf;
9891.1Snonakastruct uio;
9901.1Snonaka
9911.1Snonaka/*
9921.1Snonaka * Operations performed by bus_dmamap_sync().
9931.1Snonaka */
9941.1Snonaka#define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
9951.1Snonaka#define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
9961.1Snonaka#define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
9971.1Snonaka#define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
9981.1Snonaka
9991.1Snonakatypedef struct prep_bus_dma_tag		*bus_dma_tag_t;
10001.1Snonakatypedef struct prep_bus_dmamap		*bus_dmamap_t;
10011.1Snonaka
10021.1Snonaka/*
10031.1Snonaka *	bus_dma_segment_t
10041.1Snonaka *
10051.1Snonaka *	Describes a single contiguous DMA transaction.  Values
10061.1Snonaka *	are suitable for programming into DMA registers.
10071.1Snonaka */
10081.1Snonakastruct prep_bus_dma_segment {
10091.1Snonaka	bus_addr_t	ds_addr;	/* DMA address */
10101.1Snonaka	bus_size_t	ds_len;		/* length of transfer */
10111.1Snonaka};
10121.1Snonakatypedef struct prep_bus_dma_segment	bus_dma_segment_t;
10131.1Snonaka
10141.1Snonaka/*
10151.1Snonaka *	bus_dma_tag_t
10161.1Snonaka *
10171.1Snonaka *	A machine-dependent opaque type describing the implementation of
10181.1Snonaka *	DMA for a given bus.
10191.1Snonaka */
10201.1Snonaka
10211.1Snonakastruct prep_bus_dma_tag {
10221.1Snonaka	/*
10231.1Snonaka	 * The `bounce threshold' is checked while we are loading
10241.1Snonaka	 * the DMA map.  If the physical address of the segment
10251.1Snonaka	 * exceeds the threshold, an error will be returned.  The
10261.1Snonaka	 * caller can then take whatever action is necessary to
10271.1Snonaka	 * bounce the transfer.  If this value is 0, it will be
10281.1Snonaka	 * ignored.
10291.1Snonaka	 */
10301.1Snonaka	bus_addr_t _bounce_thresh;
10311.1Snonaka
10321.1Snonaka	/*
10331.1Snonaka	 * DMA mapping methods.
10341.1Snonaka	 */
10351.1Snonaka	int	(*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
10361.1Snonaka		    bus_size_t, bus_size_t, int, bus_dmamap_t *));
10371.1Snonaka	void	(*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
10381.1Snonaka	int	(*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
10391.1Snonaka		    bus_size_t, struct proc *, int));
10401.1Snonaka	int	(*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
10411.1Snonaka		    struct mbuf *, int));
10421.1Snonaka	int	(*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
10431.1Snonaka		    struct uio *, int));
10441.1Snonaka	int	(*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
10451.1Snonaka		    bus_dma_segment_t *, int, bus_size_t, int));
10461.1Snonaka	void	(*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
10471.1Snonaka	void	(*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
10481.1Snonaka		    bus_addr_t, bus_size_t, int));
10491.1Snonaka
10501.1Snonaka	/*
10511.1Snonaka	 * DMA memory utility functions.
10521.1Snonaka	 */
10531.1Snonaka	int	(*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
10541.1Snonaka		    bus_size_t, bus_dma_segment_t *, int, int *, int));
10551.1Snonaka	void	(*_dmamem_free) __P((bus_dma_tag_t,
10561.1Snonaka		    bus_dma_segment_t *, int));
10571.1Snonaka	int	(*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
10581.1Snonaka		    int, size_t, caddr_t *, int));
10591.1Snonaka	void	(*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
10601.3Ssimonb	paddr_t	(*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
10611.3Ssimonb		    int, off_t, int, int));
10621.1Snonaka};
10631.1Snonaka
10641.1Snonaka#define	bus_dmamap_create(t, s, n, m, b, f, p)			\
10651.1Snonaka	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
10661.1Snonaka#define	bus_dmamap_destroy(t, p)				\
10671.1Snonaka	(*(t)->_dmamap_destroy)((t), (p))
10681.1Snonaka#define	bus_dmamap_load(t, m, b, s, p, f)			\
10691.1Snonaka	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
10701.1Snonaka#define	bus_dmamap_load_mbuf(t, m, b, f)			\
10711.1Snonaka	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
10721.1Snonaka#define	bus_dmamap_load_uio(t, m, u, f)				\
10731.1Snonaka	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
10741.1Snonaka#define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
10751.1Snonaka	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
10761.1Snonaka#define	bus_dmamap_unload(t, p)					\
10771.1Snonaka	(*(t)->_dmamap_unload)((t), (p))
10781.1Snonaka#define	bus_dmamap_sync(t, p, o, l, ops)			\
10791.1Snonaka	(void)((t)->_dmamap_sync ?				\
10801.1Snonaka	    (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
10811.1Snonaka
10821.1Snonaka#define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
10831.1Snonaka	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
10841.1Snonaka#define	bus_dmamem_free(t, sg, n)				\
10851.1Snonaka	(*(t)->_dmamem_free)((t), (sg), (n))
10861.1Snonaka#define	bus_dmamem_map(t, sg, n, s, k, f)			\
10871.1Snonaka	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
10881.1Snonaka#define	bus_dmamem_unmap(t, k, s)				\
10891.1Snonaka	(*(t)->_dmamem_unmap)((t), (k), (s))
10901.1Snonaka#define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
10911.1Snonaka	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
10921.1Snonaka
10931.1Snonaka/*
10941.1Snonaka *	bus_dmamap_t
10951.1Snonaka *
10961.1Snonaka *	Describes a DMA mapping.
10971.1Snonaka */
10981.1Snonakastruct prep_bus_dmamap {
10991.1Snonaka	/*
11001.1Snonaka	 * PRIVATE MEMBERS: not for use my machine-independent code.
11011.1Snonaka	 */
11021.1Snonaka	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
11031.1Snonaka	int		_dm_segcnt;	/* number of segs this map can map */
11041.1Snonaka	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
11051.1Snonaka	bus_size_t	_dm_boundary;	/* don't cross this */
11061.1Snonaka	bus_addr_t	_dm_bounce_thresh; /* bounce threshold; see tag */
11071.1Snonaka	int		_dm_flags;	/* misc. flags */
11081.1Snonaka
11091.1Snonaka	void		*_dm_cookie;	/* cookie for bus-specific functions */
11101.1Snonaka
11111.1Snonaka	/*
11121.1Snonaka	 * PUBLIC MEMBERS: these are used by machine-independent code.
11131.1Snonaka	 */
11141.1Snonaka	bus_size_t	dm_mapsize;	/* size of the mapping */
11151.1Snonaka	int		dm_nsegs;	/* # valid segments in mapping */
11161.1Snonaka	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
11171.1Snonaka};
11181.1Snonaka
11191.1Snonaka#ifdef _PREP_BUS_DMA_PRIVATE
11201.1Snonakaint	_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
11211.1Snonaka	    bus_size_t, int, bus_dmamap_t *));
11221.1Snonakavoid	_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
11231.1Snonakaint	_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
11241.1Snonaka	    bus_size_t, struct proc *, int));
11251.1Snonakaint	_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
11261.1Snonaka	    struct mbuf *, int));
11271.1Snonakaint	_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
11281.1Snonaka	    struct uio *, int));
11291.1Snonakaint	_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
11301.1Snonaka	    bus_dma_segment_t *, int, bus_size_t, int));
11311.1Snonakavoid	_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
11321.1Snonakavoid	_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
11331.1Snonaka	    bus_size_t, int));
11341.1Snonaka
11351.1Snonakaint	_bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
11361.1Snonaka	    bus_size_t alignment, bus_size_t boundary,
11371.1Snonaka	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
11381.1Snonakavoid	_bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
11391.1Snonaka	    int nsegs));
11401.1Snonakaint	_bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
11411.1Snonaka	    int nsegs, size_t size, caddr_t *kvap, int flags));
11421.1Snonakavoid	_bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
11431.1Snonaka	    size_t size));
11441.3Ssimonbpaddr_t	_bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
11451.3Ssimonb	    int nsegs, off_t off, int prot, int flags));
11461.1Snonaka
11471.1Snonakaint	_bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
11481.1Snonaka	    bus_size_t alignment, bus_size_t boundary,
11491.1Snonaka	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
11501.1Snonaka	    paddr_t low, paddr_t high));
11511.1Snonaka#endif /* _PREP_BUS_DMA_PRIVATE */
11521.1Snonaka#endif /* _PREP_BUS_H_ */
1153