Home | History | Annotate | Line # | Download | only in include
bus.h revision 1.1
      1 /*	$NetBSD: bus.h,v 1.1 2005/12/29 15:20:08 tsutsui 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 barrier operations.  The ews4800mips does not currently require
    534  * barriers, but we must provide the flags to MI code.
    535  */
    536 #define	bus_space_barrier(t, h, o, l, f)				\
    537 ({									\
    538 	wbflush();							\
    539 })
    540 
    541 
    542 #define	BUS_SPACE_BARRIER_READ	0x01
    543 #define	BUS_SPACE_BARRIER_WRITE	0x02
    544 
    545 
    546 /*
    547  * Bus read (single) operations.
    548  */
    549 #define	bus_space_read_1(t, h, o)	__ebs_rs(1,uint8_t,(t),(h),(o))
    550 #define	bus_space_read_2(t, h, o)	__ebs_rs(2,uint16_t,(t),(h),(o))
    551 #define	bus_space_read_4(t, h, o)	__ebs_rs(4,uint32_t,(t),(h),(o))
    552 #define	bus_space_read_8(t, h, o)	__ebs_rs(8,uint64_t,(t),(h),(o))
    553 
    554 
    555 /*
    556  * Bus read multiple operations.
    557  */
    558 #define	bus_space_read_multi_1(t, h, o, a, c)				\
    559 	__ebs_nonsingle(rm,1,uint8_t,(t),(h),(o),(a),(c))
    560 #define	bus_space_read_multi_2(t, h, o, a, c)				\
    561 	__ebs_nonsingle(rm,2,uint16_t,(t),(h),(o),(a),(c))
    562 #define	bus_space_read_multi_4(t, h, o, a, c)				\
    563 	__ebs_nonsingle(rm,4,uint32_t,(t),(h),(o),(a),(c))
    564 #define	bus_space_read_multi_8(t, h, o, a, c)				\
    565 	__ebs_nonsingle(rm,8,uint64_t,(t),(h),(o),(a),(c))
    566 
    567 
    568 /*
    569  * Bus read region operations.
    570  */
    571 #define	bus_space_read_region_1(t, h, o, a, c)				\
    572 	__ebs_nonsingle(rr,1,uint8_t,(t),(h),(o),(a),(c))
    573 #define	bus_space_read_region_2(t, h, o, a, c)				\
    574 	__ebs_nonsingle(rr,2,uint16_t,(t),(h),(o),(a),(c))
    575 #define	bus_space_read_region_4(t, h, o, a, c)				\
    576 	__ebs_nonsingle(rr,4,uint32_t,(t),(h),(o),(a),(c))
    577 #define	bus_space_read_region_8(t, h, o, a, c)				\
    578 	__ebs_nonsingle(rr,8,uint64_t,(t),(h),(o),(a),(c))
    579 
    580 
    581 /*
    582  * Bus write (single) operations.
    583  */
    584 #define	bus_space_write_1(t, h, o, v)	__ebs_ws(1,uint8_t,(t),(h),(o),(v))
    585 #define	bus_space_write_2(t, h, o, v)	__ebs_ws(2,uint16_t,(t),(h),(o),(v))
    586 #define	bus_space_write_4(t, h, o, v)	__ebs_ws(4,uint32_t,(t),(h),(o),(v))
    587 #define	bus_space_write_8(t, h, o, v)	__ebs_ws(8,uint64_t,(t),(h),(o),(v))
    588 
    589 
    590 /*
    591  * Bus write multiple operations.
    592  */
    593 #define	bus_space_write_multi_1(t, h, o, a, c)				\
    594 	__ebs_nonsingle(wm,1,uint8_t,(t),(h),(o),(a),(c))
    595 #define	bus_space_write_multi_2(t, h, o, a, c)				\
    596 	__ebs_nonsingle(wm,2,uint16_t,(t),(h),(o),(a),(c))
    597 #define	bus_space_write_multi_4(t, h, o, a, c)				\
    598 	__ebs_nonsingle(wm,4,uint32_t,(t),(h),(o),(a),(c))
    599 #define	bus_space_write_multi_8(t, h, o, a, c)				\
    600 	__ebs_nonsingle(wm,8,uint64_t,(t),(h),(o),(a),(c))
    601 
    602 
    603 /*
    604  * Bus write region operations.
    605  */
    606 #define	bus_space_write_region_1(t, h, o, a, c)				\
    607 	__ebs_nonsingle(wr,1,uint8_t,(t),(h),(o),(a),(c))
    608 #define	bus_space_write_region_2(t, h, o, a, c)				\
    609 	__ebs_nonsingle(wr,2,uint16_t,(t),(h),(o),(a),(c))
    610 #define	bus_space_write_region_4(t, h, o, a, c)				\
    611 	__ebs_nonsingle(wr,4,uint32_t,(t),(h),(o),(a),(c))
    612 #define	bus_space_write_region_8(t, h, o, a, c)				\
    613 	__ebs_nonsingle(wr,8,uint64_t,(t),(h),(o),(a),(c))
    614 
    615 
    616 /*
    617  * Set multiple operations.
    618  */
    619 #define	bus_space_set_multi_1(t, h, o, v, c)				\
    620 	__ebs_set(sm,1,uint8_t,(t),(h),(o),(v),(c))
    621 #define	bus_space_set_multi_2(t, h, o, v, c)				\
    622 	__ebs_set(sm,2,uint16_t,(t),(h),(o),(v),(c))
    623 #define	bus_space_set_multi_4(t, h, o, v, c)				\
    624 	__ebs_set(sm,4,uint32_t,(t),(h),(o),(v),(c))
    625 #define	bus_space_set_multi_8(t, h, o, v, c)				\
    626 	__ebs_set(sm,8,uint64_t,(t),(h),(o),(v),(c))
    627 
    628 
    629 /*
    630  * Set region operations.
    631  */
    632 #define	bus_space_set_region_1(t, h, o, v, c)				\
    633 	__ebs_set(sr,1,uint8_t,(t),(h),(o),(v),(c))
    634 #define	bus_space_set_region_2(t, h, o, v, c)				\
    635 	__ebs_set(sr,2,uint16_t,(t),(h),(o),(v),(c))
    636 #define	bus_space_set_region_4(t, h, o, v, c)				\
    637 	__ebs_set(sr,4,uint32_t,(t),(h),(o),(v),(c))
    638 #define	bus_space_set_region_8(t, h, o, v, c)				\
    639 	__ebs_set(sr,8,uint64_t,(t),(h),(o),(v),(c))
    640 
    641 
    642 /*
    643  * Copy region operations.
    644  */
    645 #define	bus_space_copy_region_1(t, h1, o1, h2, o2, c)			\
    646 	__ebs_copy(1, uint8_t, (t), (h1), (o1), (h2), (o2), (c))
    647 #define	bus_space_copy_region_2(t, h1, o1, h2, o2, c)			\
    648 	__ebs_copy(2, uint16_t, (t), (h1), (o1), (h2), (o2), (c))
    649 #define	bus_space_copy_region_4(t, h1, o1, h2, o2, c)			\
    650 	__ebs_copy(4, uint32_t, (t), (h1), (o1), (h2), (o2), (c))
    651 #define	bus_space_copy_region_8(t, h1, o1, h2, o2, c)			\
    652 	__ebs_copy(8, uint64_t, (t), (h1), (o1), (h2), (o2), (c))
    653 
    654 /*
    655  * Bus stream operations--defined in terms of non-stream counterparts
    656  */
    657 #define	__BUS_SPACE_HAS_STREAM_METHODS 1
    658 #define	bus_space_read_stream_1 bus_space_read_1
    659 #define	bus_space_read_stream_2 bus_space_read_2
    660 #define	bus_space_read_stream_4 bus_space_read_4
    661 #define	bus_space_read_stream_8 bus_space_read_8
    662 #define	bus_space_read_multi_stream_1 bus_space_read_multi_1
    663 #define	bus_space_read_multi_stream_2 bus_space_read_multi_2
    664 #define	bus_space_read_multi_stream_4 bus_space_read_multi_4
    665 #define	bus_space_read_multi_stream_8 bus_space_read_multi_8
    666 #define	bus_space_read_region_stream_1 bus_space_read_region_1
    667 #define	bus_space_read_region_stream_2 bus_space_read_region_2
    668 #define	bus_space_read_region_stream_4 bus_space_read_region_4
    669 #define	bus_space_read_region_stream_8 bus_space_read_region_8
    670 #define	bus_space_write_stream_1 bus_space_write_1
    671 #define	bus_space_write_stream_2 bus_space_write_2
    672 #define	bus_space_write_stream_4 bus_space_write_4
    673 #define	bus_space_write_stream_8 bus_space_write_8
    674 #define	bus_space_write_multi_stream_1 bus_space_write_multi_1
    675 #define	bus_space_write_multi_stream_2 bus_space_write_multi_2
    676 #define	bus_space_write_multi_stream_4 bus_space_write_multi_4
    677 #define	bus_space_write_multi_stream_8 bus_space_write_multi_8
    678 #define	bus_space_write_region_stream_1 bus_space_write_region_1
    679 #define	bus_space_write_region_stream_2 bus_space_write_region_2
    680 #define	bus_space_write_region_stream_4 bus_space_write_region_4
    681 #define	bus_space_write_region_stream_8	bus_space_write_region_8
    682 
    683 #endif /* _KERNEL */
    684 
    685 /*
    686  * Flags used in various bus DMA methods.
    687  */
    688 #define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
    689 #define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
    690 #define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
    691 #define	BUS_DMA_COHERENT	0x004	/* hint: map memory DMA coherent */
    692 #define	BUS_DMA_STREAMING	0x008	/* hint: sequential, unidirectional */
    693 #define	BUS_DMA_BUS1		0x010	/* placeholders for bus functions... */
    694 #define	BUS_DMA_BUS2		0x020
    695 #define	BUS_DMA_BUS3		0x040
    696 #define	BUS_DMA_BUS4		0x080
    697 #define	BUS_DMA_READ		0x100	/* mapping is device -> memory only */
    698 #define	BUS_DMA_WRITE		0x200	/* mapping is memory -> device only */
    699 #define	BUS_DMA_NOCACHE		0x400	/* hint: map non-cached memory */
    700 
    701 #define	EWS4800MIPS_DMAMAP_COHERENT	0x10000	/* no cache flush necessary on sync */
    702 
    703 /* Forwards needed by prototypes below. */
    704 struct mbuf;
    705 struct uio;
    706 
    707 /*
    708  * Operations performed by bus_dmamap_sync().
    709  */
    710 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
    711 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
    712 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
    713 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
    714 
    715 typedef struct ews4800mips_bus_dma_tag		*bus_dma_tag_t;
    716 typedef struct ews4800mips_bus_dmamap		*bus_dmamap_t;
    717 
    718 #define	BUS_DMA_TAG_VALID(t)    ((t) != (bus_dma_tag_t)0)
    719 
    720 /*
    721  *	bus_dma_segment_t
    722  *
    723  *	Describes a single contiguous DMA transaction.  Values
    724  *	are suitable for programming into DMA registers.
    725  */
    726 struct ews4800mips_bus_dma_segment {
    727 	bus_addr_t	ds_addr;	/* DMA address */
    728 	bus_size_t	ds_len;		/* length of transfer */
    729 	bus_addr_t	_ds_vaddr;	/* virtual address, 0 if invalid */
    730 };
    731 typedef struct ews4800mips_bus_dma_segment	bus_dma_segment_t;
    732 
    733 /*
    734  *	bus_dma_tag_t
    735  *
    736  *	A machine-dependent opaque type describing the implementation of
    737  *	DMA for a given bus.
    738  */
    739 
    740 struct ews4800mips_bus_dma_tag {
    741 	/*
    742 	 * DMA mapping methods.
    743 	 */
    744 	int	(*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
    745 		    bus_size_t, bus_size_t, int, bus_dmamap_t *);
    746 	void	(*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
    747 	int	(*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
    748 		    bus_size_t, struct proc *, int);
    749 	int	(*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
    750 		    struct mbuf *, int);
    751 	int	(*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
    752 		    struct uio *, int);
    753 	int	(*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
    754 		    bus_dma_segment_t *, int, bus_size_t, int);
    755 	void	(*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
    756 	void	(*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
    757 		    bus_addr_t, bus_size_t, int);
    758 
    759 	/*
    760 	 * DMA memory utility functions.
    761 	 */
    762 	int	(*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
    763 		    bus_size_t, bus_dma_segment_t *, int, int *, int);
    764 	void	(*_dmamem_free)(bus_dma_tag_t,
    765 		    bus_dma_segment_t *, int);
    766 	int	(*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
    767 		    int, size_t, caddr_t *, int);
    768 	void	(*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t);
    769 	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
    770 		    int, off_t, int, int);
    771 
    772 	/*
    773 	 * DMA controller private.
    774 	 */
    775 	void	*_dmachip_cookie;
    776 };
    777 
    778 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
    779 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
    780 #define	bus_dmamap_destroy(t, p)				\
    781 	(*(t)->_dmamap_destroy)((t), (p))
    782 #define	bus_dmamap_load(t, m, b, s, p, f)			\
    783 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
    784 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
    785 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
    786 #define	bus_dmamap_load_uio(t, m, u, f)				\
    787 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
    788 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
    789 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
    790 #define	bus_dmamap_unload(t, p)					\
    791 	(*(t)->_dmamap_unload)((t), (p))
    792 #define	bus_dmamap_sync(t, p, o, l, ops)			\
    793 	(*(t)->_dmamap_sync)((t), (p), (o), (l), (ops))
    794 
    795 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
    796 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
    797 #define	bus_dmamem_free(t, sg, n)				\
    798 	(*(t)->_dmamem_free)((t), (sg), (n))
    799 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
    800 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
    801 #define	bus_dmamem_unmap(t, k, s)				\
    802 	(*(t)->_dmamem_unmap)((t), (k), (s))
    803 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
    804 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
    805 
    806 /*
    807  *	bus_dmamap_t
    808  *
    809  *	Describes a DMA mapping.
    810  */
    811 struct ews4800mips_bus_dmamap {
    812 	/*
    813 	 * PRIVATE MEMBERS: not for use my machine-independent code.
    814 	 */
    815 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
    816 	int		_dm_segcnt;	/* number of segs this map can map */
    817 	bus_size_t	_dm_maxmaxsegsz; /* fixed largest possible segment */
    818 	bus_size_t	_dm_boundary;	/* don't cross this */
    819 	int		_dm_flags;	/* misc. flags */
    820 
    821 	/*
    822 	 * PUBLIC MEMBERS: these are used by machine-independent code.
    823 	 */
    824 	bus_size_t	dm_maxsegsz;	/* largest possible segment */
    825 	bus_size_t	dm_mapsize;	/* size of the mapping */
    826 	int		dm_nsegs;	/* # valid segments in mapping */
    827 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
    828 };
    829 
    830 #ifdef _EWS4800MIPS_BUS_DMA_PRIVATE
    831 int	_bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
    832 	    bus_size_t, int, bus_dmamap_t *);
    833 void	_bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
    834 int	_bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
    835 	    bus_size_t, struct proc *, int);
    836 int	_bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
    837 	    struct mbuf *, int);
    838 int	_bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t,
    839 	    struct uio *, int);
    840 int	_bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
    841 	    bus_dma_segment_t *, int, bus_size_t, int);
    842 void	_bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
    843 void	_bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
    844 	    bus_size_t, int);
    845 
    846 int	_bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
    847 	    bus_size_t alignment, bus_size_t boundary,
    848 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
    849 void	_bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
    850 	    int nsegs);
    851 int	_bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
    852 	    int nsegs, size_t size, caddr_t *kvap, int flags);
    853 void	_bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva,
    854 	    size_t size);
    855 paddr_t	_bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
    856 	    int nsegs, off_t off, int prot, int flags);
    857 
    858 int	_bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
    859 	    bus_size_t alignment, bus_size_t boundary,
    860 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
    861 	    vaddr_t low, vaddr_t high);
    862 
    863 extern struct ews4800mips_bus_dma_tag ews4800mips_default_bus_dma_tag;
    864 #endif /* _EWS4800MIPS_BUS_DMA_PRIVATE */
    865 
    866 #endif /* _EWS4800MIPS_BUS_H_ */
    867