Home | History | Annotate | Line # | Download | only in include
bus.h revision 1.4
      1 /*	$NetBSD: bus.h,v 1.4 2007/02/21 20:41:24 mrg Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1997, 1998, 2000, 2001, 2005 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9  * NASA Ames Research Center.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  * 3. All advertising materials mentioning features or use of this software
     20  *    must display the following acknowledgement:
     21  *	This product includes software developed by the NetBSD
     22  *	Foundation, Inc. and its contributors.
     23  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24  *    contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37  * POSSIBILITY OF SUCH DAMAGE.
     38  */
     39 
     40 /*
     41  * Copyright (c) 1996 Carnegie-Mellon University.
     42  * All rights reserved.
     43  *
     44  * Author: Chris G. Demetriou
     45  *
     46  * Permission to use, copy, modify and distribute this software and
     47  * its documentation is hereby granted, provided that both the copyright
     48  * notice and this permission notice appear in all copies of the
     49  * software, derivative works or modified versions, and any portions
     50  * thereof, and that both notices appear in supporting documentation.
     51  *
     52  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     53  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     54  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     55  *
     56  * Carnegie Mellon requests users of this software to return to
     57  *
     58  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     59  *  School of Computer Science
     60  *  Carnegie Mellon University
     61  *  Pittsburgh PA 15213-3890
     62  *
     63  * any improvements or extensions that they make and grant Carnegie the
     64  * rights to redistribute these changes.
     65  */
     66 
     67 #ifndef _EWS4800MIPS_BUS_H_
     68 #define	_EWS4800MIPS_BUS_H_
     69 
     70 #include <sys/types.h>
     71 #ifdef _KERNEL
     72 /*
     73  * Turn on BUS_SPACE_DEBUG if the global DEBUG option is enabled.
     74  */
     75 #if defined(DEBUG) && !defined(BUS_SPACE_DEBUG)
     76 #define	BUS_SPACE_DEBUG
     77 #endif
     78 
     79 #ifdef BUS_SPACE_DEBUG
     80 #include <sys/systm.h> /* for printf() prototype */
     81 /*
     82  * Macros for checking the aligned-ness of pointers passed to bus
     83  * space ops.  Strict alignment is required by the MIPS architecture,
     84  * and a trap will occur if unaligned access is performed.  These
     85  * may aid in the debugging of a broken device driver by displaying
     86  * useful information about the problem.
     87  */
     88 #define	__BUS_SPACE_ALIGNED_ADDRESS(p, t)				\
     89 	((((uint32_t)(p)) & (sizeof(t)-1)) == 0)
     90 
     91 #define	__BUS_SPACE_ADDRESS_SANITY(p, t, d)				\
     92 ({									\
     93 	if (__BUS_SPACE_ALIGNED_ADDRESS((p), t) == 0) {			\
     94 		printf("%s 0x%x not aligned to %u bytes %s:%d\n",	\
     95 		    d, (uint32_t)(p), (uint32_t)sizeof(t), __FILE__,	\
     96 		    __LINE__);						\
     97 	}								\
     98 	(void) 0;							\
     99 })
    100 
    101 #define	BUS_SPACE_ALIGNED_POINTER(p, t) __BUS_SPACE_ALIGNED_ADDRESS(p, t)
    102 #else
    103 #define	__BUS_SPACE_ADDRESS_SANITY(p, t, d)	(void) 0
    104 #define	BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
    105 #endif /* BUS_SPACE_DEBUG */
    106 #endif /* _KERNEL */
    107 
    108 /*
    109  * Addresses (in bus space).
    110  */
    111 typedef long bus_addr_t;
    112 typedef long bus_size_t;
    113 
    114 /*
    115  * Access methods for bus space.
    116  */
    117 typedef struct ews4800mips_bus_space *bus_space_tag_t;
    118 typedef bus_addr_t bus_space_handle_t;
    119 
    120 struct extent; /* forward declaration */
    121 
    122 struct ews4800mips_bus_space {
    123 	struct extent	*ebs_extent;
    124 	bus_addr_t	ebs_base_addr;
    125 	bus_size_t	ebs_size;
    126 
    127 	/* cookie */
    128 	void		*ebs_cookie;
    129 
    130 	/* mapping/unmapping */
    131 	int		(*ebs_map)(void *, bus_addr_t, bus_size_t,
    132 			    int, bus_space_handle_t *);
    133 	void		(*ebs_unmap)(void *, bus_space_handle_t,
    134 			    bus_size_t);
    135 	int		(*ebs_subregion)(void *, bus_space_handle_t,
    136 			    bus_size_t, bus_size_t, bus_space_handle_t *);
    137 
    138 	/* allocation/deallocation */
    139 	int		(*ebs_alloc)(void *, bus_addr_t, bus_addr_t,
    140 			    bus_size_t, bus_size_t, bus_size_t, int,
    141 			    bus_addr_t *, bus_space_handle_t *);
    142 	void		(*ebs_free)(void *, bus_space_handle_t,
    143 			    bus_size_t);
    144 
    145 	/* get kernel virtual address */
    146 	void *		(*ebs_vaddr)(void *, bus_space_handle_t);
    147 
    148 	/* read (single) */
    149 	uint8_t		(*ebs_r_1)(void *, bus_space_handle_t,
    150 			    bus_size_t);
    151 	uint16_t	(*ebs_r_2)(void *, bus_space_handle_t,
    152 			    bus_size_t);
    153 	uint32_t	(*ebs_r_4)(void *, bus_space_handle_t,
    154 			    bus_size_t);
    155 	uint64_t	(*ebs_r_8)(void *, bus_space_handle_t,
    156 			    bus_size_t);
    157 
    158 	/* read multiple */
    159 	void		(*ebs_rm_1)(void *, bus_space_handle_t,
    160 			    bus_size_t, uint8_t *, bus_size_t);
    161 	void		(*ebs_rm_2)(void *, bus_space_handle_t,
    162 			    bus_size_t, uint16_t *, bus_size_t);
    163 	void		(*ebs_rm_4)(void *, bus_space_handle_t,
    164 			    bus_size_t, uint32_t *, bus_size_t);
    165 	void		(*ebs_rm_8)(void *, bus_space_handle_t,
    166 			    bus_size_t, uint64_t *, bus_size_t);
    167 
    168 	/* read region */
    169 	void		(*ebs_rr_1)(void *, bus_space_handle_t,
    170 			    bus_size_t, uint8_t *, bus_size_t);
    171 	void		(*ebs_rr_2)(void *, bus_space_handle_t,
    172 			    bus_size_t, uint16_t *, bus_size_t);
    173 	void		(*ebs_rr_4)(void *, bus_space_handle_t,
    174 			    bus_size_t, uint32_t *, bus_size_t);
    175 	void		(*ebs_rr_8)(void *, bus_space_handle_t,
    176 			    bus_size_t, uint64_t *, bus_size_t);
    177 
    178 	/* write (single) */
    179 	void		(*ebs_w_1)(void *, bus_space_handle_t,
    180 			    bus_size_t, uint8_t);
    181 	void		(*ebs_w_2)(void *, bus_space_handle_t,
    182 			    bus_size_t, uint16_t);
    183 	void		(*ebs_w_4)(void *, bus_space_handle_t,
    184 			    bus_size_t, uint32_t);
    185 	void		(*ebs_w_8)(void *, bus_space_handle_t,
    186 			    bus_size_t, uint64_t);
    187 
    188 	/* write multiple */
    189 	void		(*ebs_wm_1)(void *, bus_space_handle_t,
    190 			    bus_size_t, const uint8_t *, bus_size_t);
    191 	void		(*ebs_wm_2)(void *, bus_space_handle_t,
    192 			    bus_size_t, const uint16_t *, bus_size_t);
    193 	void		(*ebs_wm_4)(void *, bus_space_handle_t,
    194 			    bus_size_t, const uint32_t *, bus_size_t);
    195 	void		(*ebs_wm_8)(void *, bus_space_handle_t,
    196 			    bus_size_t, const uint64_t *, bus_size_t);
    197 
    198 	/* write region */
    199 	void		(*ebs_wr_1)(void *, bus_space_handle_t,
    200 			    bus_size_t, const uint8_t *, bus_size_t);
    201 	void		(*ebs_wr_2)(void *, bus_space_handle_t,
    202 			    bus_size_t, const uint16_t *, bus_size_t);
    203 	void		(*ebs_wr_4)(void *, bus_space_handle_t,
    204 			    bus_size_t, const uint32_t *, bus_size_t);
    205 	void		(*ebs_wr_8)(void *, bus_space_handle_t,
    206 			    bus_size_t, const uint64_t *, bus_size_t);
    207 
    208 	/* set multiple */
    209 	void		(*ebs_sm_1)(void *, bus_space_handle_t,
    210 			    bus_size_t, uint8_t, bus_size_t);
    211 	void		(*ebs_sm_2)(void *, bus_space_handle_t,
    212 			    bus_size_t, uint16_t, bus_size_t);
    213 	void		(*ebs_sm_4)(void *, bus_space_handle_t,
    214 			    bus_size_t, uint32_t, bus_size_t);
    215 	void		(*ebs_sm_8)(void *, bus_space_handle_t,
    216 			    bus_size_t, uint64_t, bus_size_t);
    217 
    218 	/* set region */
    219 	void		(*ebs_sr_1)(void *, bus_space_handle_t,
    220 			    bus_size_t, uint8_t, bus_size_t);
    221 	void		(*ebs_sr_2)(void *, bus_space_handle_t,
    222 			    bus_size_t, uint16_t, bus_size_t);
    223 	void		(*ebs_sr_4)(void *, bus_space_handle_t,
    224 			    bus_size_t, uint32_t, bus_size_t);
    225 	void		(*ebs_sr_8)(void *, bus_space_handle_t,
    226 			    bus_size_t, uint64_t, bus_size_t);
    227 
    228 	/* copy */
    229 	void		(*ebs_c_1)(void *, bus_space_handle_t, bus_size_t,
    230 			    bus_space_handle_t, bus_size_t, bus_size_t);
    231 	void		(*ebs_c_2)(void *, bus_space_handle_t, bus_size_t,
    232 			    bus_space_handle_t, bus_size_t, bus_size_t);
    233 	void		(*ebs_c_4)(void *, bus_space_handle_t, bus_size_t,
    234 			    bus_space_handle_t, bus_size_t, bus_size_t);
    235 	void		(*ebs_c_8)(void *, bus_space_handle_t, bus_size_t,
    236 			    bus_space_handle_t, bus_size_t, bus_size_t);
    237 };
    238 
    239 #ifdef _KERNEL
    240 /* Don't use locore.h wbflush */
    241 #undef wbflush
    242 #define	wbflush()	platform.wbflush()
    243 #ifdef _EWS4800MIPS_BUS_SPACE_PRIVATE
    244 
    245 #ifndef __read_1
    246 #define	__read_1(a)	(*(volatile uint8_t *)(a))
    247 #endif
    248 #ifndef __read_2
    249 #define	__read_2(a)	(*(volatile uint16_t *)(a))
    250 #endif
    251 #ifndef __read_4
    252 #define	__read_4(a)	(*(volatile uint32_t *)(a))
    253 #endif
    254 #ifndef __read_8
    255 #define	__read_8(a)	(*(volatile uint64_t *)(a))
    256 #endif
    257 #define	__read_16(a)	"error. not yet"
    258 
    259 #ifndef __write_1
    260 #define	__write_1(a, v) {						\
    261 	*(volatile uint8_t *)(a) = (v);				\
    262 	wbflush();							\
    263 }
    264 #endif
    265 #ifndef __write_2
    266 #define	__write_2(a, v)	{						\
    267 	*(volatile uint16_t *)(a) = (v);				\
    268 	wbflush();							\
    269 }
    270 #endif
    271 #ifndef __write_4
    272 #define	__write_4(a, v)	{						\
    273 	*(volatile uint32_t *)(a) = (v);				\
    274 	wbflush();							\
    275 }
    276 #endif
    277 #ifndef __write_8
    278 #define	__write_8(a, v) {						\
    279 	*(volatile uint64_t *)(a) = (v);				\
    280 	wbflush();							\
    281 }
    282 #endif
    283 
    284 #define	__TYPENAME(BITS)	uint##BITS##_t
    285 
    286 #define	_BUS_SPACE_READ(PREFIX, BYTES, BITS)				\
    287 static __TYPENAME(BITS)							\
    288 PREFIX##_read_##BYTES(void *, bus_space_handle_t,  bus_size_t);		\
    289 static __TYPENAME(BITS)							\
    290 PREFIX##_read_##BYTES(void *tag, bus_space_handle_t bsh,		\
    291     bus_size_t offset)							\
    292 {									\
    293 	return __read_##BYTES(VADDR(bsh, offset));			\
    294 }
    295 
    296 #define	_BUS_SPACE_READ_MULTI(PREFIX, BYTES, BITS)			\
    297 static void								\
    298 PREFIX##_read_multi_##BYTES(void *, bus_space_handle_t,	bus_size_t,	\
    299     __TYPENAME(BITS) *,	bus_size_t);					\
    300 static void								\
    301 PREFIX##_read_multi_##BYTES(void *tag, bus_space_handle_t bsh,		\
    302     bus_size_t offset, __TYPENAME(BITS) *addr, bus_size_t count)	\
    303 {									\
    304 	bus_addr_t a = VADDR(bsh, offset);				\
    305 	while (count--)							\
    306 		*addr++ = __read_##BYTES(a);				\
    307 }
    308 
    309 #define	_BUS_SPACE_READ_REGION(PREFIX, BYTES, BITS)			\
    310 static void								\
    311 PREFIX##_read_region_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
    312     __TYPENAME(BITS) *, bus_size_t);					\
    313 static void								\
    314 PREFIX##_read_region_##BYTES(void *tag, bus_space_handle_t bsh,		\
    315     bus_size_t offset, __TYPENAME(BITS) *addr, bus_size_t count)	\
    316 {									\
    317 	while (count--) {						\
    318 		*addr++ = __read_##BYTES(VADDR(bsh, offset));		\
    319 		offset += BYTES;					\
    320 	}								\
    321 }
    322 
    323 #define	_BUS_SPACE_WRITE(PREFIX, BYTES, BITS)				\
    324 static void								\
    325 PREFIX##_write_##BYTES(void *, bus_space_handle_t, bus_size_t,		\
    326     __TYPENAME(BITS));							\
    327 static void								\
    328 PREFIX##_write_##BYTES(void *tag, bus_space_handle_t bsh,		\
    329     bus_size_t offset, __TYPENAME(BITS) value)				\
    330 {									\
    331 	__write_##BYTES(VADDR(bsh, offset), value);			\
    332 }
    333 
    334 #define	_BUS_SPACE_WRITE_MULTI(PREFIX, BYTES, BITS)			\
    335 static void								\
    336 PREFIX##_write_multi_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
    337     const __TYPENAME(BITS) *, bus_size_t);				\
    338 static void								\
    339 PREFIX##_write_multi_##BYTES(void *tag, bus_space_handle_t bsh,		\
    340     bus_size_t offset, const __TYPENAME(BITS) *addr, bus_size_t count)	\
    341 {									\
    342 	bus_addr_t a = VADDR(bsh, offset);				\
    343 	while (count--) {						\
    344 		__write_##BYTES(a, *addr++);				\
    345 	}								\
    346 }
    347 
    348 #define	_BUS_SPACE_WRITE_REGION(PREFIX, BYTES, BITS)			\
    349 static void								\
    350 PREFIX##_write_region_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
    351     const __TYPENAME(BITS) *, bus_size_t);				\
    352 static void								\
    353 PREFIX##_write_region_##BYTES(void *tag, bus_space_handle_t bsh,	\
    354     bus_size_t offset, const __TYPENAME(BITS) *addr, bus_size_t count)	\
    355 {									\
    356 	while (count--) {						\
    357 		__write_##BYTES(VADDR(bsh, offset), *addr++);		\
    358 		offset += BYTES;					\
    359 	}								\
    360 }
    361 
    362 #define	_BUS_SPACE_SET_MULTI(PREFIX, BYTES, BITS)			\
    363 static void								\
    364 PREFIX##_set_multi_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
    365     __TYPENAME(BITS), bus_size_t);					\
    366 static void								\
    367 PREFIX##_set_multi_##BYTES(void *tag, bus_space_handle_t bsh,		\
    368     bus_size_t offset, __TYPENAME(BITS) value, bus_size_t count)	\
    369 {									\
    370 	bus_addr_t a = VADDR(bsh, offset);				\
    371 	while (count--) {						\
    372 		__write_##BYTES(a, value);				\
    373 	}								\
    374 }
    375 
    376 #define	_BUS_SPACE_SET_REGION(PREFIX, BYTES, BITS)			\
    377 static void								\
    378 PREFIX##_set_region_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
    379     __TYPENAME(BITS), bus_size_t);					\
    380 static void								\
    381 PREFIX##_set_region_##BYTES(void *tag, bus_space_handle_t bsh,		\
    382     bus_size_t offset, __TYPENAME(BITS) value, bus_size_t count)	\
    383 {									\
    384 	while (count--) {						\
    385 		__write_##BYTES(VADDR(bsh, offset), value);		\
    386 		offset += BYTES;					\
    387 	}								\
    388 }
    389 
    390 #define	_BUS_SPACE_COPY_REGION(PREFIX, BYTES, BITS)			\
    391 static void								\
    392 PREFIX##_copy_region_##BYTES(void *, bus_space_handle_t, bus_size_t,	\
    393     bus_space_handle_t, bus_size_t, bus_size_t);			\
    394 static void								\
    395 PREFIX##_copy_region_##BYTES(void *t, bus_space_handle_t h1,		\
    396     bus_size_t o1, bus_space_handle_t h2, bus_size_t o2, bus_size_t c)	\
    397 {									\
    398 	bus_size_t o;							\
    399 	if ((h1 + o1) >= (h2 + o2)) {					\
    400 		/* src after dest: copy forward */			\
    401 		for (o = 0; c != 0; c--, o += BYTES)			\
    402 			__write_##BYTES(VADDR(h2, o2 + o),		\
    403 			    __read_##BYTES(VADDR(h1, o1 + o)));	\
    404 	} else {							\
    405 		/* dest after src: copy backwards */			\
    406 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
    407 			__write_##BYTES(VADDR(h2, o2 + o),		\
    408 			    __read_##BYTES(VADDR(h1, o1 + o)));	\
    409 	}								\
    410 }
    411 
    412 #define	_BUS_SPACE_NO_MAP						\
    413 	(int (*)(void *, bus_addr_t, bus_size_t, int,			\
    414 	bus_space_handle_t *))_bus_space_invalid_access
    415 #define	_BUS_SPACE_NO_UNMAP						\
    416 	(void (*)(void *, bus_space_handle_t, bus_size_t))		\
    417 	_bus_space_invalid_access
    418 #define	_BUS_SPACE_NO_SUBREGION						\
    419 	(int (*)(void *, bus_space_handle_t, bus_size_t, bus_size_t,	\
    420 	bus_space_handle_t *))_bus_space_invalid_access
    421 #define	_BUS_SPACE_NO_ALLOC						\
    422 	(int (*)(void *, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t,\
    423 	 bus_size_t, int, bus_addr_t *,	bus_space_handle_t *))		\
    424 	_bus_space_invalid_access
    425 #define	_BUS_SPACE_NO_FREE						\
    426 	(void (*)(void *, bus_space_handle_t, bus_size_t))		\
    427 	_bus_space_invalid_access
    428 #define	_BUS_SPACE_NO_VADDR						\
    429 	(void *(*)(void *, bus_space_handle_t))_bus_space_invalid_access
    430 #define	_BUS_SPACE_NO_READ(BYTES, BITS)					\
    431 	(uint##BITS##_t (*)(void *, bus_space_handle_t, bus_size_t))	\
    432 	_bus_space_invalid_access
    433 #define	_BUS_SPACE_NO_READ_MULTI(BYTES, BITS)				\
    434 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
    435 	uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
    436 #define	_BUS_SPACE_NO_READ_REGION(BYTES, BITS)				\
    437 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
    438 	uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
    439 #define	_BUS_SPACE_NO_WRITE(BYTES, BITS)				\
    440 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
    441 	uint##BITS##_t))_bus_space_invalid_access
    442 #define	_BUS_SPACE_NO_WRITE_MULTI(BYTES, BITS)				\
    443 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
    444 	const uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
    445 #define	_BUS_SPACE_NO_WRITE_REGION(BYTES, BITS)				\
    446 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
    447 	const uint##BITS##_t *, bus_size_t))_bus_space_invalid_access
    448 #define	_BUS_SPACE_NO_SET_MULTI(BYTES, BITS)				\
    449 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
    450 	uint##BITS##_t, bus_size_t))_bus_space_invalid_access
    451 #define	_BUS_SPACE_NO_SET_REGION(BYTES, BITS)				\
    452 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
    453 	uint##BITS##_t, bus_size_t))_bus_space_invalid_access
    454 #define	_BUS_SPACE_NO_COPY_REGION(BYTES, BITS)				\
    455 	(void (*)(void *, bus_space_handle_t, bus_size_t,		\
    456 	bus_space_handle_t, bus_size_t, bus_size_t))_bus_space_invalid_access
    457 
    458 void _bus_space_invalid_access(void);
    459 #endif /* _EWS4800MIPS_BUS_SPACE_PRIVATE */
    460 
    461 #define	__ebs_c(a,b)		__CONCAT(a,b)
    462 #define	__ebs_opname(op,size)	__ebs_c(__ebs_c(__ebs_c(ebs_,op),_),size)
    463 
    464 #define	__ebs_rs(sz, tn, t, h, o)					\
    465 	(__BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr"),		\
    466 	 (*(t)->__ebs_opname(r,sz))((t)->ebs_cookie, h, o))
    467 
    468 #define	__ebs_ws(sz, tn, t, h, o, v)					\
    469 ({									\
    470 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr");		\
    471 	(*(t)->__ebs_opname(w,sz))((t)->ebs_cookie, h, o, v);		\
    472 })
    473 
    474 #define	__ebs_nonsingle(type, sz, tn, t, h, o, a, c)			\
    475 ({									\
    476 	__BUS_SPACE_ADDRESS_SANITY((a), tn, "buffer");			\
    477 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr");		\
    478 	(*(t)->__ebs_opname(type,sz))((t)->ebs_cookie, h, o, a, c);	\
    479 })
    480 
    481 #define	__ebs_set(type, sz, tn, t, h, o, v, c)				\
    482 ({									\
    483 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), tn, "bus addr");		\
    484 	(*(t)->__ebs_opname(type,sz))((t)->ebs_cookie, h, o, v, c);	\
    485 })
    486 
    487 #define	__ebs_copy(sz, tn, t, h1, o1, h2, o2, cnt)			\
    488 ({									\
    489 	__BUS_SPACE_ADDRESS_SANITY((h1) + (o1), tn, "bus addr 1");	\
    490 	__BUS_SPACE_ADDRESS_SANITY((h2) + (o2), tn, "bus addr 2");	\
    491 	(*(t)->__ebs_opname(c,sz))((t)->ebs_cookie, h1, o1, h2, o2, cnt); \
    492 })
    493 
    494 /*
    495  * Create/destroy default bus_space tag.
    496  */
    497 int bus_space_create(bus_space_tag_t, const char *, bus_addr_t, bus_size_t);
    498 void bus_space_destroy(bus_space_tag_t);
    499 
    500 /*
    501  * Mapping and unmapping operations.
    502  */
    503 #define	bus_space_map(t, a, s, f, hp)					\
    504 	(*(t)->ebs_map)((t)->ebs_cookie, (a), (s), (f), (hp))
    505 #define	bus_space_unmap(t, h, s)					\
    506 	(*(t)->ebs_unmap)((t)->ebs_cookie, (h), (s))
    507 #define	bus_space_subregion(t, h, o, s, hp)				\
    508 	(*(t)->ebs_subregion)((t)->ebs_cookie, (h), (o), (s), (hp))
    509 
    510 #endif /* _KERNEL */
    511 
    512 #define	BUS_SPACE_MAP_CACHEABLE		0x01
    513 #define	BUS_SPACE_MAP_LINEAR		0x02
    514 #define	BUS_SPACE_MAP_PREFETCHABLE     	0x04
    515 
    516 #ifdef _KERNEL
    517 /*
    518  * Allocation and deallocation operations.
    519  */
    520 #define	bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)			\
    521 	(*(t)->ebs_alloc)((t)->ebs_cookie, (rs), (re), (s), (a), (b),	\
    522 	    (f), (ap), (hp))
    523 #define	bus_space_free(t, h, s)						\
    524 	(*(t)->ebs_free)((t)->ebs_cookie, (h), (s))
    525 
    526 /*
    527  * Get kernel virtual address for ranges mapped BUS_SPACE_MAP_LINEAR.
    528  */
    529 #define	bus_space_vaddr(t, h)						\
    530 	(*(t)->ebs_vaddr)((t)->ebs_cookie, (h))
    531 
    532 /*
    533  * Bus read/write barrier methods.
    534  *
    535  *	void bus_space_barrier(bus_space_tag_t tag,
    536  *	    bus_space_handle_t bsh, bus_size_t offset,
    537  *	    bus_size_t len, int flags);
    538  *
    539  * On the MIPS, we just flush the write buffer.
    540  */
    541 #define	bus_space_barrier(t, h, o, l, f)				\
    542 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f),	\
    543 	 wbflush()))
    544 #define	BUS_SPACE_BARRIER_READ	0x01
    545 #define	BUS_SPACE_BARRIER_WRITE	0x02
    546 
    547 
    548 /*
    549  * Bus read (single) operations.
    550  */
    551 #define	bus_space_read_1(t, h, o)	__ebs_rs(1,uint8_t,(t),(h),(o))
    552 #define	bus_space_read_2(t, h, o)	__ebs_rs(2,uint16_t,(t),(h),(o))
    553 #define	bus_space_read_4(t, h, o)	__ebs_rs(4,uint32_t,(t),(h),(o))
    554 #define	bus_space_read_8(t, h, o)	__ebs_rs(8,uint64_t,(t),(h),(o))
    555 
    556 
    557 /*
    558  * Bus read multiple operations.
    559  */
    560 #define	bus_space_read_multi_1(t, h, o, a, c)				\
    561 	__ebs_nonsingle(rm,1,uint8_t,(t),(h),(o),(a),(c))
    562 #define	bus_space_read_multi_2(t, h, o, a, c)				\
    563 	__ebs_nonsingle(rm,2,uint16_t,(t),(h),(o),(a),(c))
    564 #define	bus_space_read_multi_4(t, h, o, a, c)				\
    565 	__ebs_nonsingle(rm,4,uint32_t,(t),(h),(o),(a),(c))
    566 #define	bus_space_read_multi_8(t, h, o, a, c)				\
    567 	__ebs_nonsingle(rm,8,uint64_t,(t),(h),(o),(a),(c))
    568 
    569 
    570 /*
    571  * Bus read region operations.
    572  */
    573 #define	bus_space_read_region_1(t, h, o, a, c)				\
    574 	__ebs_nonsingle(rr,1,uint8_t,(t),(h),(o),(a),(c))
    575 #define	bus_space_read_region_2(t, h, o, a, c)				\
    576 	__ebs_nonsingle(rr,2,uint16_t,(t),(h),(o),(a),(c))
    577 #define	bus_space_read_region_4(t, h, o, a, c)				\
    578 	__ebs_nonsingle(rr,4,uint32_t,(t),(h),(o),(a),(c))
    579 #define	bus_space_read_region_8(t, h, o, a, c)				\
    580 	__ebs_nonsingle(rr,8,uint64_t,(t),(h),(o),(a),(c))
    581 
    582 
    583 /*
    584  * Bus write (single) operations.
    585  */
    586 #define	bus_space_write_1(t, h, o, v)	__ebs_ws(1,uint8_t,(t),(h),(o),(v))
    587 #define	bus_space_write_2(t, h, o, v)	__ebs_ws(2,uint16_t,(t),(h),(o),(v))
    588 #define	bus_space_write_4(t, h, o, v)	__ebs_ws(4,uint32_t,(t),(h),(o),(v))
    589 #define	bus_space_write_8(t, h, o, v)	__ebs_ws(8,uint64_t,(t),(h),(o),(v))
    590 
    591 
    592 /*
    593  * Bus write multiple operations.
    594  */
    595 #define	bus_space_write_multi_1(t, h, o, a, c)				\
    596 	__ebs_nonsingle(wm,1,uint8_t,(t),(h),(o),(a),(c))
    597 #define	bus_space_write_multi_2(t, h, o, a, c)				\
    598 	__ebs_nonsingle(wm,2,uint16_t,(t),(h),(o),(a),(c))
    599 #define	bus_space_write_multi_4(t, h, o, a, c)				\
    600 	__ebs_nonsingle(wm,4,uint32_t,(t),(h),(o),(a),(c))
    601 #define	bus_space_write_multi_8(t, h, o, a, c)				\
    602 	__ebs_nonsingle(wm,8,uint64_t,(t),(h),(o),(a),(c))
    603 
    604 
    605 /*
    606  * Bus write region operations.
    607  */
    608 #define	bus_space_write_region_1(t, h, o, a, c)				\
    609 	__ebs_nonsingle(wr,1,uint8_t,(t),(h),(o),(a),(c))
    610 #define	bus_space_write_region_2(t, h, o, a, c)				\
    611 	__ebs_nonsingle(wr,2,uint16_t,(t),(h),(o),(a),(c))
    612 #define	bus_space_write_region_4(t, h, o, a, c)				\
    613 	__ebs_nonsingle(wr,4,uint32_t,(t),(h),(o),(a),(c))
    614 #define	bus_space_write_region_8(t, h, o, a, c)				\
    615 	__ebs_nonsingle(wr,8,uint64_t,(t),(h),(o),(a),(c))
    616 
    617 
    618 /*
    619  * Set multiple operations.
    620  */
    621 #define	bus_space_set_multi_1(t, h, o, v, c)				\
    622 	__ebs_set(sm,1,uint8_t,(t),(h),(o),(v),(c))
    623 #define	bus_space_set_multi_2(t, h, o, v, c)				\
    624 	__ebs_set(sm,2,uint16_t,(t),(h),(o),(v),(c))
    625 #define	bus_space_set_multi_4(t, h, o, v, c)				\
    626 	__ebs_set(sm,4,uint32_t,(t),(h),(o),(v),(c))
    627 #define	bus_space_set_multi_8(t, h, o, v, c)				\
    628 	__ebs_set(sm,8,uint64_t,(t),(h),(o),(v),(c))
    629 
    630 
    631 /*
    632  * Set region operations.
    633  */
    634 #define	bus_space_set_region_1(t, h, o, v, c)				\
    635 	__ebs_set(sr,1,uint8_t,(t),(h),(o),(v),(c))
    636 #define	bus_space_set_region_2(t, h, o, v, c)				\
    637 	__ebs_set(sr,2,uint16_t,(t),(h),(o),(v),(c))
    638 #define	bus_space_set_region_4(t, h, o, v, c)				\
    639 	__ebs_set(sr,4,uint32_t,(t),(h),(o),(v),(c))
    640 #define	bus_space_set_region_8(t, h, o, v, c)				\
    641 	__ebs_set(sr,8,uint64_t,(t),(h),(o),(v),(c))
    642 
    643 
    644 /*
    645  * Copy region operations.
    646  */
    647 #define	bus_space_copy_region_1(t, h1, o1, h2, o2, c)			\
    648 	__ebs_copy(1, uint8_t, (t), (h1), (o1), (h2), (o2), (c))
    649 #define	bus_space_copy_region_2(t, h1, o1, h2, o2, c)			\
    650 	__ebs_copy(2, uint16_t, (t), (h1), (o1), (h2), (o2), (c))
    651 #define	bus_space_copy_region_4(t, h1, o1, h2, o2, c)			\
    652 	__ebs_copy(4, uint32_t, (t), (h1), (o1), (h2), (o2), (c))
    653 #define	bus_space_copy_region_8(t, h1, o1, h2, o2, c)			\
    654 	__ebs_copy(8, uint64_t, (t), (h1), (o1), (h2), (o2), (c))
    655 
    656 /*
    657  * Bus stream operations--defined in terms of non-stream counterparts
    658  */
    659 #define	__BUS_SPACE_HAS_STREAM_METHODS 1
    660 #define	bus_space_read_stream_1 bus_space_read_1
    661 #define	bus_space_read_stream_2 bus_space_read_2
    662 #define	bus_space_read_stream_4 bus_space_read_4
    663 #define	bus_space_read_stream_8 bus_space_read_8
    664 #define	bus_space_read_multi_stream_1 bus_space_read_multi_1
    665 #define	bus_space_read_multi_stream_2 bus_space_read_multi_2
    666 #define	bus_space_read_multi_stream_4 bus_space_read_multi_4
    667 #define	bus_space_read_multi_stream_8 bus_space_read_multi_8
    668 #define	bus_space_read_region_stream_1 bus_space_read_region_1
    669 #define	bus_space_read_region_stream_2 bus_space_read_region_2
    670 #define	bus_space_read_region_stream_4 bus_space_read_region_4
    671 #define	bus_space_read_region_stream_8 bus_space_read_region_8
    672 #define	bus_space_write_stream_1 bus_space_write_1
    673 #define	bus_space_write_stream_2 bus_space_write_2
    674 #define	bus_space_write_stream_4 bus_space_write_4
    675 #define	bus_space_write_stream_8 bus_space_write_8
    676 #define	bus_space_write_multi_stream_1 bus_space_write_multi_1
    677 #define	bus_space_write_multi_stream_2 bus_space_write_multi_2
    678 #define	bus_space_write_multi_stream_4 bus_space_write_multi_4
    679 #define	bus_space_write_multi_stream_8 bus_space_write_multi_8
    680 #define	bus_space_write_region_stream_1 bus_space_write_region_1
    681 #define	bus_space_write_region_stream_2 bus_space_write_region_2
    682 #define	bus_space_write_region_stream_4 bus_space_write_region_4
    683 #define	bus_space_write_region_stream_8	bus_space_write_region_8
    684 
    685 #endif /* _KERNEL */
    686 
    687 /*
    688  * Flags used in various bus DMA methods.
    689  */
    690 #define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
    691 #define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
    692 #define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
    693 #define	BUS_DMA_COHERENT	0x004	/* hint: map memory DMA coherent */
    694 #define	BUS_DMA_STREAMING	0x008	/* hint: sequential, unidirectional */
    695 #define	BUS_DMA_BUS1		0x010	/* placeholders for bus functions... */
    696 #define	BUS_DMA_BUS2		0x020
    697 #define	BUS_DMA_BUS3		0x040
    698 #define	BUS_DMA_BUS4		0x080
    699 #define	BUS_DMA_READ		0x100	/* mapping is device -> memory only */
    700 #define	BUS_DMA_WRITE		0x200	/* mapping is memory -> device only */
    701 #define	BUS_DMA_NOCACHE		0x400	/* hint: map non-cached memory */
    702 
    703 #define	EWS4800MIPS_DMAMAP_COHERENT	0x10000	/* no cache flush necessary on sync */
    704 
    705 /* Forwards needed by prototypes below. */
    706 struct mbuf;
    707 struct uio;
    708 
    709 /*
    710  * Operations performed by bus_dmamap_sync().
    711  */
    712 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
    713 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
    714 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
    715 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
    716 
    717 typedef struct ews4800mips_bus_dma_tag		*bus_dma_tag_t;
    718 typedef struct ews4800mips_bus_dmamap		*bus_dmamap_t;
    719 
    720 #define	BUS_DMA_TAG_VALID(t)    ((t) != (bus_dma_tag_t)0)
    721 
    722 /*
    723  *	bus_dma_segment_t
    724  *
    725  *	Describes a single contiguous DMA transaction.  Values
    726  *	are suitable for programming into DMA registers.
    727  */
    728 struct ews4800mips_bus_dma_segment {
    729 	bus_addr_t	ds_addr;	/* DMA address */
    730 	bus_size_t	ds_len;		/* length of transfer */
    731 	vaddr_t		_ds_vaddr;	/* virtual address, 0 if invalid */
    732 };
    733 typedef struct ews4800mips_bus_dma_segment	bus_dma_segment_t;
    734 
    735 /*
    736  *	bus_dma_tag_t
    737  *
    738  *	A machine-dependent opaque type describing the implementation of
    739  *	DMA for a given bus.
    740  */
    741 
    742 struct ews4800mips_bus_dma_tag {
    743 	/*
    744 	 * DMA mapping methods.
    745 	 */
    746 	int	(*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
    747 		    bus_size_t, bus_size_t, int, bus_dmamap_t *);
    748 	void	(*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
    749 	int	(*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
    750 		    bus_size_t, struct proc *, int);
    751 	int	(*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
    752 		    struct mbuf *, int);
    753 	int	(*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
    754 		    struct uio *, int);
    755 	int	(*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
    756 		    bus_dma_segment_t *, int, bus_size_t, int);
    757 	void	(*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
    758 	void	(*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
    759 		    bus_addr_t, bus_size_t, int);
    760 
    761 	/*
    762 	 * DMA memory utility functions.
    763 	 */
    764 	int	(*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
    765 		    bus_size_t, bus_dma_segment_t *, int, int *, int);
    766 	void	(*_dmamem_free)(bus_dma_tag_t,
    767 		    bus_dma_segment_t *, int);
    768 	int	(*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
    769 		    int, size_t, caddr_t *, int);
    770 	void	(*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t);
    771 	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
    772 		    int, off_t, int, int);
    773 
    774 	/*
    775 	 * DMA controller private.
    776 	 */
    777 	void	*_dmachip_cookie;
    778 };
    779 
    780 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
    781 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
    782 #define	bus_dmamap_destroy(t, p)				\
    783 	(*(t)->_dmamap_destroy)((t), (p))
    784 #define	bus_dmamap_load(t, m, b, s, p, f)			\
    785 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
    786 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
    787 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
    788 #define	bus_dmamap_load_uio(t, m, u, f)				\
    789 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
    790 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
    791 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
    792 #define	bus_dmamap_unload(t, p)					\
    793 	(*(t)->_dmamap_unload)((t), (p))
    794 #define	bus_dmamap_sync(t, p, o, l, ops)			\
    795 	(*(t)->_dmamap_sync)((t), (p), (o), (l), (ops))
    796 
    797 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
    798 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
    799 #define	bus_dmamem_free(t, sg, n)				\
    800 	(*(t)->_dmamem_free)((t), (sg), (n))
    801 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
    802 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
    803 #define	bus_dmamem_unmap(t, k, s)				\
    804 	(*(t)->_dmamem_unmap)((t), (k), (s))
    805 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
    806 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
    807 
    808 #define bus_dmatag_subregion(t, mna, mxa, nt, f) EOPNOTSUPP
    809 #define bus_dmatag_destroy(t)
    810 
    811 /*
    812  *	bus_dmamap_t
    813  *
    814  *	Describes a DMA mapping.
    815  */
    816 struct ews4800mips_bus_dmamap {
    817 	/*
    818 	 * PRIVATE MEMBERS: not for use my machine-independent code.
    819 	 */
    820 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
    821 	int		_dm_segcnt;	/* number of segs this map can map */
    822 	bus_size_t	_dm_maxmaxsegsz; /* fixed largest possible segment */
    823 	bus_size_t	_dm_boundary;	/* don't cross this */
    824 	int		_dm_flags;	/* misc. flags */
    825 	struct vmspace	*_dm_vmspace;	/* vmspace that owns the mapping */
    826 
    827 	/*
    828 	 * PUBLIC MEMBERS: these are used by machine-independent code.
    829 	 */
    830 	bus_size_t	dm_maxsegsz;	/* largest possible segment */
    831 	bus_size_t	dm_mapsize;	/* size of the mapping */
    832 	int		dm_nsegs;	/* # valid segments in mapping */
    833 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
    834 };
    835 
    836 #ifdef _EWS4800MIPS_BUS_DMA_PRIVATE
    837 int	_bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
    838 	    bus_size_t, int, bus_dmamap_t *);
    839 void	_bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
    840 int	_bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
    841 	    bus_size_t, struct proc *, int);
    842 int	_bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
    843 	    struct mbuf *, int);
    844 int	_bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t,
    845 	    struct uio *, int);
    846 int	_bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
    847 	    bus_dma_segment_t *, int, bus_size_t, int);
    848 void	_bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
    849 void	_bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
    850 	    bus_size_t, int);
    851 
    852 int	_bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
    853 	    bus_size_t alignment, bus_size_t boundary,
    854 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
    855 void	_bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
    856 	    int nsegs);
    857 int	_bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
    858 	    int nsegs, size_t size, caddr_t *kvap, int flags);
    859 void	_bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva,
    860 	    size_t size);
    861 paddr_t	_bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
    862 	    int nsegs, off_t off, int prot, int flags);
    863 
    864 int	_bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
    865 	    bus_size_t alignment, bus_size_t boundary,
    866 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
    867 	    vaddr_t low, vaddr_t high);
    868 
    869 extern struct ews4800mips_bus_dma_tag ews4800mips_default_bus_dma_tag;
    870 #endif /* _EWS4800MIPS_BUS_DMA_PRIVATE */
    871 
    872 #endif /* _EWS4800MIPS_BUS_H_ */
    873