bus.h revision 1.14
11.14Sthorpej/*	$NetBSD: bus.h,v 1.14 2001/03/07 22:42:19 thorpej Exp $	*/
21.1Sjonathan
31.5Sthorpej/*-
41.14Sthorpej * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
51.3Sjonathan * All rights reserved.
61.1Sjonathan *
71.5Sthorpej * This code is derived from software contributed to The NetBSD Foundation
81.5Sthorpej * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
91.5Sthorpej * NASA Ames Research Center.
101.5Sthorpej *
111.3Sjonathan * Redistribution and use in source and binary forms, with or without
121.3Sjonathan * modification, are permitted provided that the following conditions
131.3Sjonathan * are met:
141.3Sjonathan * 1. Redistributions of source code must retain the above copyright
151.3Sjonathan *    notice, this list of conditions and the following disclaimer.
161.3Sjonathan * 2. Redistributions in binary form must reproduce the above copyright
171.3Sjonathan *    notice, this list of conditions and the following disclaimer in the
181.3Sjonathan *    documentation and/or other materials provided with the distribution.
191.3Sjonathan * 3. All advertising materials mentioning features or use of this software
201.3Sjonathan *    must display the following acknowledgement:
211.5Sthorpej *	This product includes software developed by the NetBSD
221.5Sthorpej *	Foundation, Inc. and its contributors.
231.5Sthorpej * 4. Neither the name of The NetBSD Foundation nor the names of its
241.5Sthorpej *    contributors may be used to endorse or promote products derived
251.5Sthorpej *    from this software without specific prior written permission.
261.5Sthorpej *
271.5Sthorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
281.5Sthorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
291.5Sthorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
301.5Sthorpej * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
311.5Sthorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
321.5Sthorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
331.5Sthorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
341.5Sthorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
351.5Sthorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
361.5Sthorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
371.5Sthorpej * POSSIBILITY OF SUCH DAMAGE.
381.1Sjonathan */
391.1Sjonathan
401.1Sjonathan#ifndef _PMAX_BUS_H_
411.1Sjonathan#define _PMAX_BUS_H_
421.2Sjonathan
431.5Sthorpej#include <mips/locore.h>
441.2Sjonathan
451.5Sthorpej/*
461.5Sthorpej * Utility macros; do not use outside this file.
471.5Sthorpej */
481.5Sthorpej#define	__PB_TYPENAME_PREFIX(BITS)	___CONCAT(u_int,BITS)
491.5Sthorpej#define	__PB_TYPENAME(BITS)		___CONCAT(__PB_TYPENAME_PREFIX(BITS),_t)
501.1Sjonathan
511.1Sjonathan/*
521.1Sjonathan * Bus address and size types
531.1Sjonathan */
541.1Sjonathantypedef u_long bus_addr_t;
551.1Sjonathantypedef u_long bus_size_t;
561.1Sjonathan
571.1Sjonathan/*
581.5Sthorpej * Access methods for bus resources and address space.
591.1Sjonathan */
601.5Sthorpejtypedef int	bus_space_tag_t;
611.5Sthorpejtypedef u_long	bus_space_handle_t;
621.1Sjonathan
631.5Sthorpej/*
641.5Sthorpej *	int bus_space_map __P((bus_space_tag_t t, bus_addr_t addr,
651.5Sthorpej *	    bus_size_t size, int flags, bus_space_handle_t *bshp));
661.5Sthorpej *
671.5Sthorpej * Map a region of bus space.
681.5Sthorpej */
691.5Sthorpej
701.5Sthorpej#define	BUS_SPACE_MAP_CACHEABLE		0x01
711.5Sthorpej#define	BUS_SPACE_MAP_LINEAR		0x02
721.11Sdrochner#define	BUS_SPACE_MAP_PREFETCHABLE	0x04
731.5Sthorpej
741.5Sthorpejint	bus_space_map __P((bus_space_tag_t, bus_addr_t, bus_size_t,
751.5Sthorpej	    int, bus_space_handle_t *));
761.5Sthorpej
771.5Sthorpej/*
781.5Sthorpej *	void bus_space_unmap __P((bus_space_tag_t t,
791.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t size));
801.5Sthorpej *
811.5Sthorpej * Unmap a region of bus space.
821.5Sthorpej */
831.5Sthorpej
841.5Sthorpejvoid	bus_space_unmap __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
851.1Sjonathan
861.1Sjonathan/*
871.5Sthorpej *	int bus_space_subregion __P((bus_space_tag_t t,
881.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
891.5Sthorpej *	    bus_space_handle_t *nbshp));
901.5Sthorpej *
911.5Sthorpej * Get a new handle for a subregion of an already-mapped area of bus space.
921.1Sjonathan */
931.1Sjonathan
941.5Sthorpejint	bus_space_subregion __P((bus_space_tag_t t, bus_space_handle_t bsh,
951.5Sthorpej	    bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp));
961.1Sjonathan
971.5Sthorpej/*
981.5Sthorpej *	int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t, rstart,
991.5Sthorpej *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
1001.5Sthorpej *	    bus_size_t boundary, int flags, bus_addr_t *addrp,
1011.5Sthorpej *	    bus_space_handle_t *bshp));
1021.5Sthorpej *
1031.5Sthorpej * Allocate a region of bus space.
1041.5Sthorpej */
1051.1Sjonathan
1061.5Sthorpejint	bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
1071.5Sthorpej	    bus_addr_t rend, bus_size_t size, bus_size_t align,
1081.5Sthorpej	    bus_size_t boundary, int cacheable, bus_addr_t *addrp,
1091.5Sthorpej	    bus_space_handle_t *bshp));
1101.1Sjonathan
1111.5Sthorpej/*
1121.5Sthorpej *	int bus_space_free __P((bus_space_tag_t t,
1131.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t size));
1141.5Sthorpej *
1151.5Sthorpej * Free a region of bus space.
1161.5Sthorpej */
1171.1Sjonathan
1181.5Sthorpejvoid	bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
1191.5Sthorpej	    bus_size_t size));
1201.12Sdrochner
1211.12Sdrochner/*
1221.12Sdrochner *	void *bus_space_vaddr __P((bus_space_tag_t, bus_space_handle_t));
1231.12Sdrochner *
1241.12Sdrochner * Get the kernel virtual address for the mapped bus space.
1251.12Sdrochner * Only allowed for regions mapped with BUS_SPACE_MAP_LINEAR.
1261.12Sdrochner *  (XXX not enforced)
1271.12Sdrochner */
1281.12Sdrochner#define bus_space_vaddr(t, h) \
1291.12Sdrochner	((void *)(h))
1301.1Sjonathan
1311.1Sjonathan/*
1321.5Sthorpej *	u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
1331.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t offset));
1341.5Sthorpej *
1351.5Sthorpej * Read a 1, 2, 4, or 8 byte quantity from bus space
1361.5Sthorpej * described by tag/handle/offset.
1371.1Sjonathan */
1381.1Sjonathan
1391.5Sthorpej#define	bus_space_read_1(t, h, o)					\
1401.9Snisimura     ((void) t, (*(volatile u_int8_t *)((h) + (o))))
1411.5Sthorpej
1421.5Sthorpej#define	bus_space_read_2(t, h, o)					\
1431.9Snisimura     ((void) t, (*(volatile u_int16_t *)((h) + (o))))
1441.5Sthorpej
1451.5Sthorpej#define	bus_space_read_4(t, h, o)					\
1461.9Snisimura     ((void) t, (*(volatile u_int32_t *)((h) + (o))))
1471.5Sthorpej
1481.5Sthorpej#if 0	/* Cause a link error for bus_space_read_8 */
1491.5Sthorpej#define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
1501.5Sthorpej#endif
1511.1Sjonathan
1521.5Sthorpej/*
1531.5Sthorpej *	void bus_space_read_multi_N __P((bus_space_tag_t tag,
1541.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t offset,
1551.5Sthorpej *	    u_intN_t *addr, size_t count));
1561.5Sthorpej *
1571.5Sthorpej * Read `count' 1, 2, 4, or 8 byte quantities from bus space
1581.5Sthorpej * described by tag/handle/offset and copy into buffer provided.
1591.5Sthorpej */
1601.5Sthorpej
1611.5Sthorpej#define __PMAX_bus_space_read_multi(BYTES,BITS)				\
1621.5Sthorpejstatic __inline void __CONCAT(bus_space_read_multi_,BYTES)		\
1631.5Sthorpej	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
1641.5Sthorpej	__PB_TYPENAME(BITS) *, size_t));				\
1651.5Sthorpej									\
1661.5Sthorpejstatic __inline void							\
1671.5Sthorpej__CONCAT(bus_space_read_multi_,BYTES)(t, h, o, a, c)			\
1681.5Sthorpej	bus_space_tag_t t;						\
1691.5Sthorpej	bus_space_handle_t h;						\
1701.5Sthorpej	bus_size_t o;							\
1711.5Sthorpej	__PB_TYPENAME(BITS) *a;						\
1721.5Sthorpej	size_t c;							\
1731.5Sthorpej{									\
1741.5Sthorpej									\
1751.5Sthorpej	while (c--)							\
1761.5Sthorpej		*a++ = __CONCAT(bus_space_read_,BYTES)(t, h, o);	\
1771.5Sthorpej}
1781.5Sthorpej
1791.5Sthorpej__PMAX_bus_space_read_multi(1,8)
1801.5Sthorpej__PMAX_bus_space_read_multi(2,16)
1811.5Sthorpej__PMAX_bus_space_read_multi(4,32)
1821.5Sthorpej
1831.5Sthorpej#if 0	/* Cause a link error for bus_space_read_multi_8 */
1841.5Sthorpej#define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
1851.5Sthorpej#endif
1861.1Sjonathan
1871.5Sthorpej#undef __PMAX_bus_space_read_multi
1881.1Sjonathan
1891.1Sjonathan/*
1901.5Sthorpej *	void bus_space_read_region_N __P((bus_space_tag_t tag,
1911.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t offset,
1921.5Sthorpej *	    u_intN_t *addr, size_t count));
1931.5Sthorpej *
1941.5Sthorpej * Read `count' 1, 2, 4, or 8 byte quantities from bus space
1951.5Sthorpej * described by tag/handle and starting at `offset' and copy into
1961.5Sthorpej * buffer provided.
1971.1Sjonathan */
1981.1Sjonathan
1991.5Sthorpej#define __PMAX_bus_space_read_region(BYTES,BITS)			\
2001.5Sthorpejstatic __inline void __CONCAT(bus_space_read_region_,BYTES)		\
2011.5Sthorpej	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
2021.5Sthorpej	__PB_TYPENAME(BITS) *, size_t));				\
2031.5Sthorpej									\
2041.5Sthorpejstatic __inline void							\
2051.5Sthorpej__CONCAT(bus_space_read_region_,BYTES)(t, h, o, a, c)			\
2061.5Sthorpej	bus_space_tag_t t;						\
2071.5Sthorpej	bus_space_handle_t h;						\
2081.5Sthorpej	bus_size_t o;							\
2091.5Sthorpej	__PB_TYPENAME(BITS) *a;						\
2101.5Sthorpej	size_t c;							\
2111.5Sthorpej{									\
2121.5Sthorpej									\
2131.5Sthorpej	while (c--) {							\
2141.5Sthorpej		*a++ = __CONCAT(bus_space_read_,BYTES)(t, h, o);	\
2151.5Sthorpej		o += BYTES;						\
2161.5Sthorpej	}								\
2171.5Sthorpej}
2181.5Sthorpej
2191.5Sthorpej__PMAX_bus_space_read_region(1,8)
2201.5Sthorpej__PMAX_bus_space_read_region(2,16)
2211.5Sthorpej__PMAX_bus_space_read_region(4,32)
2221.5Sthorpej
2231.5Sthorpej#if 0	/* Cause a link error for bus_space_read_region_8 */
2241.5Sthorpej#define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
2251.5Sthorpej#endif
2261.1Sjonathan
2271.5Sthorpej#undef __PMAX_bus_space_read_region
2281.1Sjonathan
2291.1Sjonathan/*
2301.5Sthorpej *	void bus_space_write_N __P((bus_space_tag_t tag,
2311.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t offset,
2321.5Sthorpej *	    u_intN_t value));
2331.5Sthorpej *
2341.5Sthorpej * Write the 1, 2, 4, or 8 byte value `value' to bus space
2351.5Sthorpej * described by tag/handle/offset.
2361.1Sjonathan */
2371.1Sjonathan
2381.5Sthorpej#define	bus_space_write_1(t, h, o, v)					\
2391.5Sthorpejdo {									\
2401.5Sthorpej	(void) t;							\
2411.5Sthorpej	*(volatile u_int8_t *)((h) + (o)) = (v);			\
2421.5Sthorpej	wbflush();					/* XXX */	\
2431.5Sthorpej} while (0)
2441.5Sthorpej
2451.5Sthorpej#define	bus_space_write_2(t, h, o, v)					\
2461.5Sthorpejdo {									\
2471.5Sthorpej	(void) t;							\
2481.5Sthorpej	*(volatile u_int16_t *)((h) + (o)) = (v);			\
2491.5Sthorpej	wbflush();					/* XXX */	\
2501.5Sthorpej} while (0)
2511.5Sthorpej
2521.5Sthorpej#define	bus_space_write_4(t, h, o, v)					\
2531.5Sthorpejdo {									\
2541.5Sthorpej	(void) t;							\
2551.5Sthorpej	*(volatile u_int32_t *)((h) + (o)) = (v);			\
2561.5Sthorpej	wbflush();					/* XXX */	\
2571.5Sthorpej} while (0)
2581.5Sthorpej
2591.5Sthorpej#if 0	/* Cause a link error for bus_space_write_8 */
2601.5Sthorpej#define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
2611.5Sthorpej#endif
2621.5Sthorpej
2631.5Sthorpej/*
2641.5Sthorpej *	void bus_space_write_multi_N __P((bus_space_tag_t tag,
2651.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t offset,
2661.5Sthorpej *	    const u_intN_t *addr, size_t count));
2671.5Sthorpej *
2681.5Sthorpej * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
2691.5Sthorpej * provided to bus space described by tag/handle/offset.
2701.5Sthorpej */
2711.5Sthorpej
2721.5Sthorpej#define __PMAX_bus_space_write_multi(BYTES,BITS)			\
2731.5Sthorpejstatic __inline void __CONCAT(bus_space_write_multi_,BYTES)		\
2741.5Sthorpej	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
2751.5Sthorpej	__PB_TYPENAME(BITS) *, size_t));				\
2761.5Sthorpej									\
2771.5Sthorpejstatic __inline void							\
2781.5Sthorpej__CONCAT(bus_space_write_multi_,BYTES)(t, h, o, a, c)			\
2791.5Sthorpej	bus_space_tag_t t;						\
2801.5Sthorpej	bus_space_handle_t h;						\
2811.5Sthorpej	bus_size_t o;							\
2821.5Sthorpej	__PB_TYPENAME(BITS) *a;						\
2831.5Sthorpej	size_t c;							\
2841.5Sthorpej{									\
2851.5Sthorpej									\
2861.5Sthorpej	while (c--)							\
2871.5Sthorpej		__CONCAT(bus_space_write_,BYTES)(t, h, o, *a++);	\
2881.5Sthorpej}
2891.5Sthorpej
2901.5Sthorpej__PMAX_bus_space_write_multi(1,8)
2911.5Sthorpej__PMAX_bus_space_write_multi(2,16)
2921.5Sthorpej__PMAX_bus_space_write_multi(4,32)
2931.5Sthorpej
2941.5Sthorpej#if 0	/* Cause a link error for bus_space_write_8 */
2951.5Sthorpej#define	bus_space_write_multi_8(t, h, o, a, c)				\
2961.5Sthorpej			!!! bus_space_write_multi_8 unimplimented !!!
2971.5Sthorpej#endif
2981.5Sthorpej
2991.5Sthorpej#undef __PMAX_bus_space_write_multi
3001.5Sthorpej
3011.5Sthorpej/*
3021.5Sthorpej *	void bus_space_write_region_N __P((bus_space_tag_t tag,
3031.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t offset,
3041.5Sthorpej *	    const u_intN_t *addr, size_t count));
3051.5Sthorpej *
3061.5Sthorpej * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
3071.5Sthorpej * to bus space described by tag/handle starting at `offset'.
3081.5Sthorpej */
3091.1Sjonathan
3101.5Sthorpej#define __PMAX_bus_space_write_region(BYTES,BITS)			\
3111.5Sthorpejstatic __inline void __CONCAT(bus_space_write_region_,BYTES)		\
3121.5Sthorpej	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
3131.5Sthorpej	__PB_TYPENAME(BITS) *, size_t));				\
3141.5Sthorpej									\
3151.5Sthorpejstatic __inline void							\
3161.5Sthorpej__CONCAT(bus_space_write_region_,BYTES)(t, h, o, a, c)			\
3171.5Sthorpej	bus_space_tag_t t;						\
3181.5Sthorpej	bus_space_handle_t h;						\
3191.5Sthorpej	bus_size_t o;							\
3201.5Sthorpej	__PB_TYPENAME(BITS) *a;						\
3211.5Sthorpej	size_t c;							\
3221.5Sthorpej{									\
3231.5Sthorpej									\
3241.5Sthorpej	while (c--) {							\
3251.5Sthorpej		__CONCAT(bus_space_write_,BYTES)(t, h, o, *a++);	\
3261.5Sthorpej		o += BYTES;						\
3271.5Sthorpej	}								\
3281.5Sthorpej}
3291.5Sthorpej
3301.5Sthorpej__PMAX_bus_space_write_region(1,8)
3311.5Sthorpej__PMAX_bus_space_write_region(2,16)
3321.5Sthorpej__PMAX_bus_space_write_region(4,32)
3331.5Sthorpej
3341.5Sthorpej#if 0	/* Cause a link error for bus_space_write_region_8 */
3351.5Sthorpej#define	bus_space_write_region_8					\
3361.5Sthorpej			!!! bus_space_write_region_8 unimplemented !!!
3371.5Sthorpej#endif
3381.1Sjonathan
3391.5Sthorpej#undef __PMAX_bus_space_write_region
3401.1Sjonathan
3411.1Sjonathan/*
3421.5Sthorpej *	void bus_space_set_multi_N __P((bus_space_tag_t tag,
3431.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
3441.5Sthorpej *	    size_t count));
3451.5Sthorpej *
3461.5Sthorpej * Write the 1, 2, 4, or 8 byte value `val' to bus space described
3471.5Sthorpej * by tag/handle/offset `count' times.
3481.5Sthorpej */
3491.5Sthorpej
3501.5Sthorpej#define __PMAX_bus_space_set_multi(BYTES,BITS)				\
3511.5Sthorpejstatic __inline void __CONCAT(bus_space_set_multi_,BYTES)		\
3521.5Sthorpej	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
3531.5Sthorpej	__PB_TYPENAME(BITS), size_t));					\
3541.5Sthorpej									\
3551.5Sthorpejstatic __inline void							\
3561.5Sthorpej__CONCAT(bus_space_set_multi_,BYTES)(t, h, o, v, c)			\
3571.5Sthorpej	bus_space_tag_t t;						\
3581.5Sthorpej	bus_space_handle_t h;						\
3591.5Sthorpej	bus_size_t o;							\
3601.5Sthorpej	__PB_TYPENAME(BITS) v;						\
3611.5Sthorpej	size_t c;							\
3621.5Sthorpej{									\
3631.5Sthorpej									\
3641.5Sthorpej	while (c--)							\
3651.5Sthorpej		__CONCAT(bus_space_write_,BYTES)(t, h, o, v);		\
3661.5Sthorpej}
3671.5Sthorpej
3681.5Sthorpej__PMAX_bus_space_set_multi(1,8)
3691.5Sthorpej__PMAX_bus_space_set_multi(2,16)
3701.5Sthorpej__PMAX_bus_space_set_multi(4,32)
3711.5Sthorpej
3721.5Sthorpej#if 0	/* Cause a link error for bus_space_set_multi_8 */
3731.5Sthorpej#define	bus_space_set_multi_8						\
3741.5Sthorpej			!!! bus_space_set_multi_8 unimplemented !!!
3751.5Sthorpej#endif
3761.5Sthorpej
3771.5Sthorpej#undef __PMAX_bus_space_set_multi
3781.5Sthorpej
3791.5Sthorpej/*
3801.5Sthorpej *	void bus_space_set_region_N __P((bus_space_tag_t tag,
3811.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
3821.5Sthorpej *	    size_t count));
3831.5Sthorpej *
3841.5Sthorpej * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
3851.5Sthorpej * by tag/handle starting at `offset'.
3861.5Sthorpej */
3871.5Sthorpej
3881.5Sthorpej#define __PMAX_bus_space_set_region(BYTES,BITS)				\
3891.5Sthorpejstatic __inline void __CONCAT(bus_space_set_region_,BYTES)		\
3901.5Sthorpej	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
3911.5Sthorpej	__PB_TYPENAME(BITS), size_t));					\
3921.5Sthorpej									\
3931.5Sthorpejstatic __inline void							\
3941.5Sthorpej__CONCAT(bus_space_set_region_,BYTES)(t, h, o, v, c)			\
3951.5Sthorpej	bus_space_tag_t t;						\
3961.5Sthorpej	bus_space_handle_t h;						\
3971.5Sthorpej	bus_size_t o;							\
3981.5Sthorpej	__PB_TYPENAME(BITS) v;						\
3991.5Sthorpej	size_t c;							\
4001.5Sthorpej{									\
4011.5Sthorpej									\
4021.5Sthorpej	while (c--) {							\
4031.5Sthorpej		__CONCAT(bus_space_write_,BYTES)(t, h, o, v);		\
4041.5Sthorpej		o += BYTES;						\
4051.5Sthorpej	}								\
4061.5Sthorpej}
4071.5Sthorpej
4081.5Sthorpej__PMAX_bus_space_set_region(1,8)
4091.5Sthorpej__PMAX_bus_space_set_region(2,16)
4101.5Sthorpej__PMAX_bus_space_set_region(4,32)
4111.5Sthorpej
4121.5Sthorpej#if 0	/* Cause a link error for bus_space_set_region_8 */
4131.5Sthorpej#define	bus_space_set_region_8						\
4141.5Sthorpej			!!! bus_space_set_region_8 unimplemented !!!
4151.5Sthorpej#endif
4161.5Sthorpej
4171.5Sthorpej#undef __PMAX_bus_space_set_region
4181.5Sthorpej
4191.5Sthorpej/*
4201.5Sthorpej *	void bus_space_copy_region_N __P((bus_space_tag_t tag,
4211.5Sthorpej *	    bus_space_handle_t bsh1, bus_size_t off1,
4221.5Sthorpej *	    bus_space_handle_t bsh2, bus_size_t off2,
4231.5Sthorpej *	    bus_size_t count));
4241.5Sthorpej *
4251.5Sthorpej * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
4261.5Sthorpej * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
4271.5Sthorpej */
4281.5Sthorpej
4291.5Sthorpej#define	__PMAX_copy_region(BYTES)					\
4301.5Sthorpejstatic __inline void __CONCAT(bus_space_copy_region_,BYTES)		\
4311.5Sthorpej	__P((bus_space_tag_t,						\
4321.5Sthorpej	    bus_space_handle_t bsh1, bus_size_t off1,			\
4331.5Sthorpej	    bus_space_handle_t bsh2, bus_size_t off2,			\
4341.5Sthorpej	    bus_size_t count));						\
4351.5Sthorpej									\
4361.5Sthorpejstatic __inline void							\
4371.5Sthorpej__CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c)		\
4381.5Sthorpej	bus_space_tag_t t;						\
4391.5Sthorpej	bus_space_handle_t h1, h2;					\
4401.5Sthorpej	bus_size_t o1, o2, c;						\
4411.5Sthorpej{									\
4421.5Sthorpej	bus_size_t o;							\
4431.5Sthorpej									\
4441.5Sthorpej	if ((h1 + o1) >= (h2 + o2)) {					\
4451.5Sthorpej		/* src after dest: copy forward */			\
4461.5Sthorpej		for (o = 0; c != 0; c--, o += BYTES)			\
4471.5Sthorpej			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
4481.5Sthorpej			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
4491.5Sthorpej	} else {							\
4501.5Sthorpej		/* dest after src: copy backwards */			\
4511.5Sthorpej		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
4521.5Sthorpej			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
4531.5Sthorpej			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
4541.5Sthorpej	}								\
4551.5Sthorpej}
4561.5Sthorpej
4571.5Sthorpej__PMAX_copy_region(1)
4581.5Sthorpej__PMAX_copy_region(2)
4591.5Sthorpej__PMAX_copy_region(4)
4601.5Sthorpej
4611.5Sthorpej#if 0	/* Cause a link error for bus_space_copy_region_8 */
4621.5Sthorpej#define	bus_space_copy_region_8						\
4631.5Sthorpej			!!! bus_space_copy_region_8 unimplemented !!!
4641.5Sthorpej#endif
4651.5Sthorpej
4661.5Sthorpej#undef __PMAX_copy_region
4671.5Sthorpej
4681.5Sthorpej/*
4691.5Sthorpej * Bus read/write barrier methods.
4701.5Sthorpej *
4711.5Sthorpej *	void bus_space_barrier __P((bus_space_tag_t tag,
4721.5Sthorpej *	    bus_space_handle_t bsh, bus_size_t offset,
4731.5Sthorpej *	    bus_size_t len, int flags));
4741.5Sthorpej *
4751.5Sthorpej * On the MIPS, we just flush the write buffer.
4761.5Sthorpej */
4771.5Sthorpej#define	bus_space_barrier(t, h, o, l, f)	\
4781.5Sthorpej	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)),	\
4791.5Sthorpej	 wbflush())
4801.5Sthorpej#define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
4811.5Sthorpej#define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
4821.5Sthorpej
4831.5Sthorpej#undef __PB_TYPENAME_PREFIX
4841.5Sthorpej#undef __PB_TYPENAME
4851.8Sdrochner
4861.8Sdrochner#define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
4871.5Sthorpej
4881.5Sthorpej/*
4891.5Sthorpej * Flags used in various bus DMA methods.
4901.5Sthorpej */
4911.5Sthorpej#define	BUS_DMA_WAITOK		0x00	/* safe to sleep (pseudo-flag) */
4921.5Sthorpej#define	BUS_DMA_NOWAIT		0x01	/* not safe to sleep */
4931.5Sthorpej#define	BUS_DMA_ALLOCNOW	0x02	/* perform resource allocation now */
4941.5Sthorpej#define	BUS_DMA_COHERENT	0x04	/* hint: map memory DMA coherent */
4951.14Sthorpej#define	BUS_DMA_STREAMING	0x08	/* hint: sequential, unidirectional */
4961.5Sthorpej#define	BUS_DMA_BUS1		0x10	/* placeholders for bus functions... */
4971.5Sthorpej#define	BUS_DMA_BUS2		0x20
4981.5Sthorpej#define	BUS_DMA_BUS3		0x40
4991.5Sthorpej#define	BUS_DMA_BUS4		0x80
5001.5Sthorpej
5011.5Sthorpej#define	PMAX_DMAMAP_COHERENT	0x100	/* no cache flush necessary on sync */
5021.5Sthorpej
5031.5Sthorpej/* Forwards needed by prototypes below. */
5041.5Sthorpejstruct mbuf;
5051.5Sthorpejstruct uio;
5061.5Sthorpej
5071.5Sthorpej/*
5081.5Sthorpej * Operations performed by bus_dmamap_sync().
5091.5Sthorpej */
5101.5Sthorpej#define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
5111.5Sthorpej#define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
5121.5Sthorpej#define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
5131.5Sthorpej#define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
5141.5Sthorpej
5151.5Sthorpejtypedef struct pmax_bus_dma_tag		*bus_dma_tag_t;
5161.5Sthorpejtypedef struct pmax_bus_dmamap		*bus_dmamap_t;
5171.5Sthorpej
5181.5Sthorpej/*
5191.5Sthorpej *	bus_dma_segment_t
5201.5Sthorpej *
5211.5Sthorpej *	Describes a single contiguous DMA transaction.  Values
5221.5Sthorpej *	are suitable for programming into DMA registers.
5231.5Sthorpej */
5241.5Sthorpejstruct pmax_bus_dma_segment {
5251.5Sthorpej	bus_addr_t	ds_addr;	/* DMA address */
5261.5Sthorpej	bus_size_t	ds_len;		/* length of transfer */
5271.6Sthorpej	bus_addr_t	_ds_vaddr;	/* virtual address, 0 if invalid */
5281.5Sthorpej};
5291.5Sthorpejtypedef struct pmax_bus_dma_segment	bus_dma_segment_t;
5301.5Sthorpej
5311.5Sthorpej/*
5321.5Sthorpej *	bus_dma_tag_t
5331.5Sthorpej *
5341.5Sthorpej *	A machine-dependent opaque type describing the implementation of
5351.5Sthorpej *	DMA for a given bus.
5361.5Sthorpej */
5371.5Sthorpej
5381.5Sthorpejstruct pmax_bus_dma_tag {
5391.5Sthorpej	/*
5401.5Sthorpej	 * DMA mapping methods.
5411.5Sthorpej	 */
5421.5Sthorpej	int	(*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
5431.5Sthorpej		    bus_size_t, bus_size_t, int, bus_dmamap_t *));
5441.5Sthorpej	void	(*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
5451.5Sthorpej	int	(*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
5461.5Sthorpej		    bus_size_t, struct proc *, int));
5471.5Sthorpej	int	(*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
5481.5Sthorpej		    struct mbuf *, int));
5491.5Sthorpej	int	(*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
5501.5Sthorpej		    struct uio *, int));
5511.5Sthorpej	int	(*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
5521.5Sthorpej		    bus_dma_segment_t *, int, bus_size_t, int));
5531.5Sthorpej	void	(*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
5541.5Sthorpej	void	(*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
5551.5Sthorpej		    bus_addr_t, bus_size_t, int));
5561.5Sthorpej
5571.5Sthorpej	/*
5581.5Sthorpej	 * DMA memory utility functions.
5591.5Sthorpej	 */
5601.5Sthorpej	int	(*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
5611.5Sthorpej		    bus_size_t, bus_dma_segment_t *, int, int *, int));
5621.5Sthorpej	void	(*_dmamem_free) __P((bus_dma_tag_t,
5631.5Sthorpej		    bus_dma_segment_t *, int));
5641.5Sthorpej	int	(*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
5651.5Sthorpej		    int, size_t, caddr_t *, int));
5661.5Sthorpej	void	(*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
5671.13Ssimonb	paddr_t	(*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
5681.13Ssimonb		    int, off_t, int, int));
5691.5Sthorpej};
5701.5Sthorpej
5711.5Sthorpej#define	bus_dmamap_create(t, s, n, m, b, f, p)			\
5721.5Sthorpej	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
5731.5Sthorpej#define	bus_dmamap_destroy(t, p)				\
5741.5Sthorpej	(*(t)->_dmamap_destroy)((t), (p))
5751.5Sthorpej#define	bus_dmamap_load(t, m, b, s, p, f)			\
5761.5Sthorpej	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
5771.5Sthorpej#define	bus_dmamap_load_mbuf(t, m, b, f)			\
5781.5Sthorpej	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
5791.5Sthorpej#define	bus_dmamap_load_uio(t, m, u, f)				\
5801.5Sthorpej	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
5811.5Sthorpej#define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
5821.5Sthorpej	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
5831.5Sthorpej#define	bus_dmamap_unload(t, p)					\
5841.5Sthorpej	(*(t)->_dmamap_unload)((t), (p))
5851.5Sthorpej#define	bus_dmamap_sync(t, p, o, l, ops)			\
5861.5Sthorpej	(*(t)->_dmamap_sync)((t), (p), (o), (l), (ops))
5871.5Sthorpej
5881.5Sthorpej#define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
5891.5Sthorpej	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
5901.5Sthorpej#define	bus_dmamem_free(t, sg, n)				\
5911.5Sthorpej	(*(t)->_dmamem_free)((t), (sg), (n))
5921.5Sthorpej#define	bus_dmamem_map(t, sg, n, s, k, f)			\
5931.5Sthorpej	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
5941.5Sthorpej#define	bus_dmamem_unmap(t, k, s)				\
5951.5Sthorpej	(*(t)->_dmamem_unmap)((t), (k), (s))
5961.5Sthorpej#define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
5971.5Sthorpej	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
5981.5Sthorpej
5991.5Sthorpej/*
6001.5Sthorpej *	bus_dmamap_t
6011.5Sthorpej *
6021.5Sthorpej *	Describes a DMA mapping.
6031.1Sjonathan */
6041.5Sthorpejstruct pmax_bus_dmamap {
6051.5Sthorpej	/*
6061.5Sthorpej	 * PRIVATE MEMBERS: not for use my machine-independent code.
6071.5Sthorpej	 */
6081.5Sthorpej	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
6091.5Sthorpej	int		_dm_segcnt;	/* number of segs this map can map */
6101.5Sthorpej	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
6111.5Sthorpej	bus_size_t	_dm_boundary;	/* don't cross this */
6121.5Sthorpej	int		_dm_flags;	/* misc. flags */
6131.5Sthorpej
6141.5Sthorpej	/*
6151.5Sthorpej	 * PUBLIC MEMBERS: these are used by machine-independent code.
6161.5Sthorpej	 */
6171.5Sthorpej	bus_size_t	dm_mapsize;	/* size of the mapping */
6181.5Sthorpej	int		dm_nsegs;	/* # valid segments in mapping */
6191.5Sthorpej	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
6201.5Sthorpej};
6211.5Sthorpej
6221.5Sthorpej#ifdef _PMAX_BUS_DMA_PRIVATE
6231.5Sthorpejint	_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
6241.5Sthorpej	    bus_size_t, int, bus_dmamap_t *));
6251.5Sthorpejvoid	_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
6261.5Sthorpejint	_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
6271.5Sthorpej	    bus_size_t, struct proc *, int));
6281.5Sthorpejint	_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
6291.5Sthorpej	    struct mbuf *, int));
6301.5Sthorpejint	_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
6311.5Sthorpej	    struct uio *, int));
6321.5Sthorpejint	_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
6331.5Sthorpej	    bus_dma_segment_t *, int, bus_size_t, int));
6341.5Sthorpejvoid	_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
6351.5Sthorpejvoid	_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
6361.5Sthorpej	    bus_size_t, int));
6371.5Sthorpej
6381.5Sthorpejint	_bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
6391.5Sthorpej	    bus_size_t alignment, bus_size_t boundary,
6401.5Sthorpej	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
6411.5Sthorpejvoid	_bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
6421.5Sthorpej	    int nsegs));
6431.5Sthorpejint	_bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
6441.5Sthorpej	    int nsegs, size_t size, caddr_t *kvap, int flags));
6451.5Sthorpejvoid	_bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
6461.5Sthorpej	    size_t size));
6471.13Ssimonbpaddr_t	_bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
6481.13Ssimonb	    int nsegs, off_t off, int prot, int flags));
6491.5Sthorpej
6501.5Sthorpejint	_bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
6511.5Sthorpej	    bus_size_t alignment, bus_size_t boundary,
6521.5Sthorpej	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
6531.7Snisimura	    vaddr_t low, vaddr_t high));
6541.1Sjonathan
6551.5Sthorpejextern struct pmax_bus_dma_tag pmax_default_bus_dma_tag;
6561.5Sthorpej#endif /* _PMAX_BUS_DMA_PRIVATE */
6571.1Sjonathan
6581.10Sad#endif /* !_PMAX_BUS_H_ */
659