Home | History | Annotate | Line # | Download | only in include
bus.h revision 1.11
      1 /*     $NetBSD: bus.h,v 1.11 2001/07/19 15:32:13 thorpej Exp $   */
      2 
      3 /*-
      4  * Copyright (c) 1996, 1997, 1998, 2001 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 #ifndef _HPCMIPS_BUS_H_
     41 #define _HPCMIPS_BUS_H_
     42 
     43 #include <mips/locore.h>
     44 
     45 #ifdef BUS_SPACE_DEBUG
     46 #include <sys/systm.h> /* for printf() prototype */
     47 /*
     48  * Macros for checking the aligned-ness of pointers passed to bus
     49  * space ops.  Strict alignment is required by the MIPS architecture,
     50  * and a trap will occur if unaligned access is performed.  These
     51  * may aid in the debugging of a broken device driver by displaying
     52  * useful information about the problem.
     53  */
     54 #define	__BUS_SPACE_ALIGNED_ADDRESS(p, t)				\
     55 	((((u_long)(p)) & (sizeof(t)-1)) == 0)
     56 
     57 #define	__BUS_SPACE_ADDRESS_SANITY(p, t, d)				\
     58 ({									\
     59 	if (__BUS_SPACE_ALIGNED_ADDRESS((p), t) == 0) {			\
     60 		printf("%s 0x%lx not aligned to %d bytes %s:%d\n",	\
     61 		    d, (u_long)(p), sizeof(t), __FILE__, __LINE__);	\
     62 	}								\
     63 	(void) 0;							\
     64 })
     65 
     66 #define BUS_SPACE_ALIGNED_POINTER(p, t) __BUS_SPACE_ALIGNED_ADDRESS(p, t)
     67 #else
     68 #define	__BUS_SPACE_ADDRESS_SANITY(p,t,d)	(void) 0
     69 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
     70 #endif /* BUS_SPACE_DEBUG */
     71 /*
     72  * Utility macros; do not use outside this file.
     73  */
     74 #define	__PB_TYPENAME_PREFIX(BITS)	___CONCAT(u_int,BITS)
     75 #define	__PB_TYPENAME(BITS)		___CONCAT(__PB_TYPENAME_PREFIX(BITS),_t)
     76 
     77 /*
     78  * Bus address and size types
     79  */
     80 
     81 typedef u_long bus_addr_t;
     82 typedef u_long bus_size_t;
     83 
     84 /*
     85  * Access methods for bus resources and address space.
     86  */
     87 typedef struct hpcmips_bus_space	*bus_space_tag_t;
     88 typedef u_int32_t bus_space_handle_t;
     89 /*
     90  * Initialize extent.
     91  */
     92 void hpcmips_init_bus_space_extent __P((bus_space_tag_t));
     93 bus_space_tag_t hpcmips_alloc_bus_space_tag __P((void));
     94 
     95 struct hpcmips_bus_space {
     96     char t_name[16];  /* bus name */
     97     u_int32_t t_base; /* extent base */
     98     u_int32_t t_size; /* extent size */
     99     void *t_extent;
    100 };
    101 
    102 
    103 /*
    104  *	int bus_space_map __P((bus_space_tag_t t, bus_addr_t addr,
    105  *	    bus_size_t size, int flags, bus_space_handle_t *bshp));
    106  *
    107  * Map a region of bus space.
    108  */
    109 
    110 #define	BUS_SPACE_MAP_CACHEABLE		0x01
    111 #define	BUS_SPACE_MAP_LINEAR		0x02
    112 #define	BUS_SPACE_MAP_PREFETCHABLE		0x04
    113 
    114 int	bus_space_map __P((bus_space_tag_t, bus_addr_t, bus_size_t,
    115 	    int, bus_space_handle_t *));
    116 
    117 /*
    118  *	void bus_space_unmap __P((bus_space_tag_t t,
    119  *	    bus_space_handle_t bsh, bus_size_t size));
    120  *
    121  * Unmap a region of bus space.
    122  */
    123 
    124 void	bus_space_unmap __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
    125 
    126 /*
    127  *	int bus_space_subregion __P((bus_space_tag_t t,
    128  *	    bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
    129  *	    bus_space_handle_t *nbshp));
    130  *
    131  * Get a new handle for a subregion of an already-mapped area of bus space.
    132  */
    133 
    134 int	bus_space_subregion __P((bus_space_tag_t t, bus_space_handle_t bsh,
    135 	    bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp));
    136 
    137 /*
    138  *	int bus_space_alloc __P((bus_space_tag_t t, bus_addr_t, rstart,
    139  *	    bus_addr_t rend, bus_size_t size, bus_size_t align,
    140  *	    bus_size_t boundary, int flags, bus_addr_t *addrp,
    141  *	    bus_space_handle_t *bshp));
    142  *
    143  * Allocate a region of bus space.
    144  */
    145 
    146 int	bus_space_alloc __P((bus_space_tag_t t, bus_addr_t rstart,
    147 	    bus_addr_t rend, bus_size_t size, bus_size_t align,
    148 	    bus_size_t boundary, int cacheable, bus_addr_t *addrp,
    149 	    bus_space_handle_t *bshp));
    150 
    151 /*
    152  *	int bus_space_free __P((bus_space_tag_t t,
    153  *	    bus_space_handle_t bsh, bus_size_t size));
    154  *
    155  * Free a region of bus space.
    156  */
    157 
    158 void	bus_space_free __P((bus_space_tag_t t, bus_space_handle_t bsh,
    159 	    bus_size_t size));
    160 
    161 /*
    162  *	u_intN_t bus_space_read_N __P((bus_space_tag_t tag,
    163  *	    bus_space_handle_t bsh, bus_size_t offset));
    164  *
    165  * Read a 1, 2, 4, or 8 byte quantity from bus space
    166  * described by tag/handle/offset.
    167  */
    168 
    169 #define	bus_space_read_1(t, h, o)					\
    170     (wbflush(),						/* XXX */	\
    171      (void) t, (*(volatile u_int8_t *)((h) + (o))))
    172 
    173 #define	bus_space_read_2(t, h, o)					\
    174     (wbflush(),						/* XXX */	\
    175      (void) t, (*(volatile u_int16_t *)((h) + (o))))
    176 
    177 #define	bus_space_read_4(t, h, o)					\
    178     (wbflush(),						/* XXX */	\
    179      (void) t, (*(volatile u_int32_t *)((h) + (o))))
    180 
    181 #if 0	/* Cause a link error for bus_space_read_8 */
    182 #define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
    183 #endif
    184 
    185 /*
    186  *	void bus_space_read_multi_N __P((bus_space_tag_t tag,
    187  *	    bus_space_handle_t bsh, bus_size_t offset,
    188  *	    u_intN_t *addr, size_t count));
    189  *
    190  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
    191  * described by tag/handle/offset and copy into buffer provided.
    192  */
    193 
    194 #define __HPCMIPS_bus_space_read_multi(BYTES,BITS)			\
    195 static __inline void __CONCAT(bus_space_read_multi_,BYTES)		\
    196 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
    197 	__PB_TYPENAME(BITS) *, size_t));				\
    198 									\
    199 static __inline void							\
    200 __CONCAT(bus_space_read_multi_,BYTES)(t, h, o, a, c)			\
    201 	bus_space_tag_t t;						\
    202 	bus_space_handle_t h;						\
    203 	bus_size_t o;							\
    204 	__PB_TYPENAME(BITS) *a;						\
    205 	size_t c;							\
    206 {									\
    207 									\
    208 	while (c--)							\
    209 		*a++ = __CONCAT(bus_space_read_,BYTES)(t, h, o);	\
    210 }
    211 
    212 __HPCMIPS_bus_space_read_multi(1,8)
    213 __HPCMIPS_bus_space_read_multi(2,16)
    214 __HPCMIPS_bus_space_read_multi(4,32)
    215 
    216 #if 0	/* Cause a link error for bus_space_read_multi_8 */
    217 #define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
    218 #endif
    219 
    220 #undef __HPCMIPS_bus_space_read_multi
    221 
    222 /*
    223  *	void bus_space_read_region_N __P((bus_space_tag_t tag,
    224  *	    bus_space_handle_t bsh, bus_size_t offset,
    225  *	    u_intN_t *addr, size_t count));
    226  *
    227  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
    228  * described by tag/handle and starting at `offset' and copy into
    229  * buffer provided.
    230  */
    231 
    232 #define __HPCMIPS_bus_space_read_region(BYTES,BITS)			\
    233 static __inline void __CONCAT(bus_space_read_region_,BYTES)		\
    234 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
    235 	__PB_TYPENAME(BITS) *, size_t));				\
    236 									\
    237 static __inline void							\
    238 __CONCAT(bus_space_read_region_,BYTES)(t, h, o, a, c)			\
    239 	bus_space_tag_t t;						\
    240 	bus_space_handle_t h;						\
    241 	bus_size_t o;							\
    242 	__PB_TYPENAME(BITS) *a;						\
    243 	size_t c;							\
    244 {									\
    245 									\
    246 	while (c--) {							\
    247 		*a++ = __CONCAT(bus_space_read_,BYTES)(t, h, o);	\
    248 		o += BYTES;						\
    249 	}								\
    250 }
    251 
    252 __HPCMIPS_bus_space_read_region(1,8)
    253 __HPCMIPS_bus_space_read_region(2,16)
    254 __HPCMIPS_bus_space_read_region(4,32)
    255 
    256 #if 0	/* Cause a link error for bus_space_read_region_8 */
    257 #define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
    258 #endif
    259 
    260 #undef __HPCMIPS_bus_space_read_region
    261 
    262 /*
    263  *	void bus_space_write_N __P((bus_space_tag_t tag,
    264  *	    bus_space_handle_t bsh, bus_size_t offset,
    265  *	    u_intN_t value));
    266  *
    267  * Write the 1, 2, 4, or 8 byte value `value' to bus space
    268  * described by tag/handle/offset.
    269  */
    270 
    271 #define	bus_space_write_1(t, h, o, v)					\
    272 do {									\
    273 	(void) t;							\
    274 	*(volatile u_int8_t *)((h) + (o)) = (v);			\
    275 	wbflush();					/* XXX */	\
    276 } while (0)
    277 
    278 #define	bus_space_write_2(t, h, o, v)					\
    279 do {									\
    280 	(void) t;							\
    281 	*(volatile u_int16_t *)((h) + (o)) = (v);			\
    282 	wbflush();					/* XXX */	\
    283 } while (0)
    284 
    285 #define	bus_space_write_4(t, h, o, v)					\
    286 do {									\
    287 	(void) t;							\
    288 	*(volatile u_int32_t *)((h) + (o)) = (v);			\
    289 	wbflush();					/* XXX */	\
    290 } while (0)
    291 
    292 #if 0	/* Cause a link error for bus_space_write_8 */
    293 #define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
    294 #endif
    295 
    296 /*
    297  *	void bus_space_write_multi_N __P((bus_space_tag_t tag,
    298  *	    bus_space_handle_t bsh, bus_size_t offset,
    299  *	    const u_intN_t *addr, size_t count));
    300  *
    301  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
    302  * provided to bus space described by tag/handle/offset.
    303  */
    304 
    305 #define __HPCMIPS_bus_space_write_multi(BYTES,BITS)			\
    306 static __inline void __CONCAT(bus_space_write_multi_,BYTES)		\
    307 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
    308 	__PB_TYPENAME(BITS) *, size_t));				\
    309 									\
    310 static __inline void							\
    311 __CONCAT(bus_space_write_multi_,BYTES)(t, h, o, a, c)			\
    312 	bus_space_tag_t t;						\
    313 	bus_space_handle_t h;						\
    314 	bus_size_t o;							\
    315 	__PB_TYPENAME(BITS) *a;						\
    316 	size_t c;							\
    317 {									\
    318 									\
    319 	while (c--)							\
    320 		__CONCAT(bus_space_write_,BYTES)(t, h, o, *a++);	\
    321 }
    322 
    323 __HPCMIPS_bus_space_write_multi(1,8)
    324 __HPCMIPS_bus_space_write_multi(2,16)
    325 __HPCMIPS_bus_space_write_multi(4,32)
    326 
    327 #if 0	/* Cause a link error for bus_space_write_8 */
    328 #define	bus_space_write_multi_8(t, h, o, a, c)				\
    329 			!!! bus_space_write_multi_8 unimplimented !!!
    330 #endif
    331 
    332 #undef __HPCMIPS_bus_space_write_multi
    333 
    334 /*
    335  *	void bus_space_write_region_N __P((bus_space_tag_t tag,
    336  *	    bus_space_handle_t bsh, bus_size_t offset,
    337  *	    const u_intN_t *addr, size_t count));
    338  *
    339  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
    340  * to bus space described by tag/handle starting at `offset'.
    341  */
    342 
    343 #define __HPCMIPS_bus_space_write_region(BYTES,BITS)			\
    344 static __inline void __CONCAT(bus_space_write_region_,BYTES)		\
    345 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
    346 	__PB_TYPENAME(BITS) *, size_t));				\
    347 									\
    348 static __inline void							\
    349 __CONCAT(bus_space_write_region_,BYTES)(t, h, o, a, c)			\
    350 	bus_space_tag_t t;						\
    351 	bus_space_handle_t h;						\
    352 	bus_size_t o;							\
    353 	__PB_TYPENAME(BITS) *a;						\
    354 	size_t c;							\
    355 {									\
    356 									\
    357 	while (c--) {							\
    358 		__CONCAT(bus_space_write_,BYTES)(t, h, o, *a++);	\
    359 		o += BYTES;						\
    360 	}								\
    361 }
    362 
    363 __HPCMIPS_bus_space_write_region(1,8)
    364 __HPCMIPS_bus_space_write_region(2,16)
    365 __HPCMIPS_bus_space_write_region(4,32)
    366 
    367 #if 0	/* Cause a link error for bus_space_write_region_8 */
    368 #define	bus_space_write_region_8					\
    369 			!!! bus_space_write_region_8 unimplemented !!!
    370 #endif
    371 
    372 #undef __HPCMIPS_bus_space_write_region
    373 
    374 /*
    375  *	void bus_space_set_multi_N __P((bus_space_tag_t tag,
    376  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
    377  *	    size_t count));
    378  *
    379  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
    380  * by tag/handle/offset `count' times.
    381  */
    382 
    383 #define __HPCMIPS_bus_space_set_multi(BYTES,BITS)			\
    384 static __inline void __CONCAT(bus_space_set_multi_,BYTES)		\
    385 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
    386 	__PB_TYPENAME(BITS), size_t));					\
    387 									\
    388 static __inline void							\
    389 __CONCAT(bus_space_set_multi_,BYTES)(t, h, o, v, c)			\
    390 	bus_space_tag_t t;						\
    391 	bus_space_handle_t h;						\
    392 	bus_size_t o;							\
    393 	__PB_TYPENAME(BITS) v;						\
    394 	size_t c;							\
    395 {									\
    396 									\
    397 	while (c--)							\
    398 		__CONCAT(bus_space_write_,BYTES)(t, h, o, v);		\
    399 }
    400 
    401 __HPCMIPS_bus_space_set_multi(1,8)
    402 __HPCMIPS_bus_space_set_multi(2,16)
    403 __HPCMIPS_bus_space_set_multi(4,32)
    404 
    405 #if 0	/* Cause a link error for bus_space_set_multi_8 */
    406 #define	bus_space_set_multi_8						\
    407 			!!! bus_space_set_multi_8 unimplemented !!!
    408 #endif
    409 
    410 #undef __HPCMIPS_bus_space_set_multi
    411 
    412 /*
    413  *	void bus_space_set_region_N __P((bus_space_tag_t tag,
    414  *	    bus_space_handle_t bsh, bus_size_t offset, u_intN_t val,
    415  *	    size_t count));
    416  *
    417  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
    418  * by tag/handle starting at `offset'.
    419  */
    420 
    421 #define __HPCMIPS_bus_space_set_region(BYTES,BITS)			\
    422 static __inline void __CONCAT(bus_space_set_region_,BYTES)		\
    423 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,		\
    424 	__PB_TYPENAME(BITS), size_t));					\
    425 									\
    426 static __inline void							\
    427 __CONCAT(bus_space_set_region_,BYTES)(t, h, o, v, c)			\
    428 	bus_space_tag_t t;						\
    429 	bus_space_handle_t h;						\
    430 	bus_size_t o;							\
    431 	__PB_TYPENAME(BITS) v;						\
    432 	size_t c;							\
    433 {									\
    434 									\
    435 	while (c--) {							\
    436 		__CONCAT(bus_space_write_,BYTES)(t, h, o, v);		\
    437 		o += BYTES;						\
    438 	}								\
    439 }
    440 
    441 __HPCMIPS_bus_space_set_region(1,8)
    442 __HPCMIPS_bus_space_set_region(2,16)
    443 __HPCMIPS_bus_space_set_region(4,32)
    444 
    445 #if 0	/* Cause a link error for bus_space_set_region_8 */
    446 #define	bus_space_set_region_8						\
    447 			!!! bus_space_set_region_8 unimplemented !!!
    448 #endif
    449 
    450 #undef __HPCMIPS_bus_space_set_region
    451 
    452 /*
    453  *	void bus_space_copy_region_N __P((bus_space_tag_t tag,
    454  *	    bus_space_handle_t bsh1, bus_size_t off1,
    455  *	    bus_space_handle_t bsh2, bus_size_t off2,
    456  *	    bus_size_t count));
    457  *
    458  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
    459  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
    460  */
    461 
    462 #define	__HPCMIPS_copy_region(BYTES)					\
    463 static __inline void __CONCAT(bus_space_copy_region_,BYTES)		\
    464 	__P((bus_space_tag_t,						\
    465 	    bus_space_handle_t bsh1, bus_size_t off1,			\
    466 	    bus_space_handle_t bsh2, bus_size_t off2,			\
    467 	    bus_size_t count));						\
    468 									\
    469 static __inline void							\
    470 __CONCAT(bus_space_copy_region_,BYTES)(t, h1, o1, h2, o2, c)		\
    471 	bus_space_tag_t t;						\
    472 	bus_space_handle_t h1, h2;					\
    473 	bus_size_t o1, o2, c;						\
    474 {									\
    475 	bus_size_t o;							\
    476 									\
    477 	if ((h1 + o1) >= (h2 + o2)) {					\
    478 		/* src after dest: copy forward */			\
    479 		for (o = 0; c != 0; c--, o += BYTES)			\
    480 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
    481 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
    482 	} else {							\
    483 		/* dest after src: copy backwards */			\
    484 		for (o = (c - 1) * BYTES; c != 0; c--, o -= BYTES)	\
    485 			__CONCAT(bus_space_write_,BYTES)(t, h2, o2 + o,	\
    486 			    __CONCAT(bus_space_read_,BYTES)(t, h1, o1 + o)); \
    487 	}								\
    488 }
    489 
    490 __HPCMIPS_copy_region(1)
    491 __HPCMIPS_copy_region(2)
    492 __HPCMIPS_copy_region(4)
    493 
    494 #if 0	/* Cause a link error for bus_space_copy_region_8 */
    495 #define	bus_space_copy_region_8						\
    496 			!!! bus_space_copy_region_8 unimplemented !!!
    497 #endif
    498 
    499 #undef __HPCMIPS_copy_region
    500 
    501 /*
    502  * Bus read/write barrier methods.
    503  *
    504  *	void bus_space_barrier __P((bus_space_tag_t tag,
    505  *	    bus_space_handle_t bsh, bus_size_t offset,
    506  *	    bus_size_t len, int flags));
    507  *
    508  * On the MIPS, we just flush the write buffer.
    509  */
    510 #define	bus_space_barrier(t, h, o, l, f)	\
    511 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)),	\
    512 	 wbflush())
    513 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
    514 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
    515 
    516 #undef __PB_TYPENAME_PREFIX
    517 #undef __PB_TYPENAME
    518 
    519 /*
    520  * Bus stream operations--defined in terms of non-stream counterparts
    521  */
    522 #define __BUS_SPACE_HAS_STREAM_METHODS 1
    523 #define bus_space_read_stream_1 bus_space_read_1
    524 #define bus_space_read_stream_2 bus_space_read_2
    525 #define bus_space_read_stream_4 bus_space_read_4
    526 #define	bus_space_read_stream_8 bus_space_read_8
    527 #define bus_space_read_multi_stream_1 bus_space_read_multi_1
    528 #define bus_space_read_multi_stream_2 bus_space_read_multi_2
    529 #define bus_space_read_multi_stream_4 bus_space_read_multi_4
    530 #define	bus_space_read_multi_stream_8 bus_space_read_multi_8
    531 #define bus_space_read_region_stream_1 bus_space_read_region_1
    532 #define bus_space_read_region_stream_2 bus_space_read_region_2
    533 #define bus_space_read_region_stream_4 bus_space_read_region_4
    534 #define	bus_space_read_region_stream_8 bus_space_read_region_8
    535 #define bus_space_write_stream_1 bus_space_write_1
    536 #define bus_space_write_stream_2 bus_space_write_2
    537 #define bus_space_write_stream_4 bus_space_write_4
    538 #define	bus_space_write_stream_8 bus_space_write_8
    539 #define bus_space_write_multi_stream_1 bus_space_write_multi_1
    540 #define bus_space_write_multi_stream_2 bus_space_write_multi_2
    541 #define bus_space_write_multi_stream_4 bus_space_write_multi_4
    542 #define	bus_space_write_multi_stream_8 bus_space_write_multi_8
    543 #define bus_space_write_region_stream_1 bus_space_write_region_1
    544 #define bus_space_write_region_stream_2 bus_space_write_region_2
    545 #define bus_space_write_region_stream_4 bus_space_write_region_4
    546 #define	bus_space_write_region_stream_8	bus_space_write_region_8
    547 
    548 /*
    549  * Flags used in various bus DMA methods.
    550  */
    551 #define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
    552 #define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
    553 #define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
    554 #define	BUS_DMA_COHERENT	0x004	/* hint: map memory DMA coherent */
    555 #define	BUS_DMA_STREAMING	0x008	/* hint: sequential, unidirectional */
    556 #define	BUS_DMA_BUS1		0x010	/* placeholders for bus functions... */
    557 #define	BUS_DMA_BUS2		0x020
    558 #define	BUS_DMA_BUS3		0x040
    559 #define	BUS_DMA_BUS4		0x080
    560 #define	BUS_DMA_READ		0x100	/* mapping is device -> memory only */
    561 #define	BUS_DMA_WRITE		0x200	/* mapping is memory -> device only */
    562 
    563 #define	HPCMIPS_DMAMAP_COHERENT	0x100	/* no cache flush necessary on sync */
    564 
    565 /* Forwards needed by prototypes below. */
    566 struct mbuf;
    567 struct uio;
    568 
    569 /*
    570  * Operations performed by bus_dmamap_sync().
    571  */
    572 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
    573 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
    574 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
    575 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
    576 
    577 typedef struct hpcmips_bus_dma_tag	*bus_dma_tag_t;
    578 typedef struct hpcmips_bus_dmamap	*bus_dmamap_t;
    579 
    580 /*
    581  *	bus_dma_segment_t
    582  *
    583  *	Describes a single contiguous DMA transaction.  Values
    584  *	are suitable for programming into DMA registers.
    585  */
    586 struct hpcmips_bus_dma_segment {
    587 	bus_addr_t	ds_addr;	/* DMA address */
    588 	bus_size_t	ds_len;		/* length of transfer */
    589 	bus_addr_t	_ds_vaddr;	/* virtual address, 0 if invalid */
    590 };
    591 typedef struct hpcmips_bus_dma_segment	bus_dma_segment_t;
    592 
    593 /*
    594  *	bus_dma_tag_t
    595  *
    596  *	A machine-dependent opaque type describing the implementation of
    597  *	DMA for a given bus.
    598  */
    599 
    600 struct hpcmips_bus_dma_tag {
    601 	/*
    602 	 * DMA mapping methods.
    603 	 */
    604 	int	(*_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
    605 		    bus_size_t, bus_size_t, int, bus_dmamap_t *));
    606 	void	(*_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
    607 	int	(*_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
    608 		    bus_size_t, struct proc *, int));
    609 	int	(*_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
    610 		    struct mbuf *, int));
    611 	int	(*_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
    612 		    struct uio *, int));
    613 	int	(*_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
    614 		    bus_dma_segment_t *, int, bus_size_t, int));
    615 	void	(*_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
    616 	void	(*_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
    617 		    bus_addr_t, bus_size_t, int));
    618 
    619 	/*
    620 	 * DMA memory utility functions.
    621 	 */
    622 	int	(*_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
    623 		    bus_size_t, bus_dma_segment_t *, int, int *, int));
    624 	void	(*_dmamem_free) __P((bus_dma_tag_t,
    625 		    bus_dma_segment_t *, int));
    626 	int	(*_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
    627 		    int, size_t, caddr_t *, int));
    628 	void	(*_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
    629 	paddr_t	(*_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
    630 		    int, off_t, int, int));
    631 
    632 	void	*_dmamap_chipset_v;
    633 };
    634 
    635 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
    636 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
    637 #define	bus_dmamap_destroy(t, p)				\
    638 	(*(t)->_dmamap_destroy)((t), (p))
    639 #define	bus_dmamap_load(t, m, b, s, p, f)			\
    640 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
    641 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
    642 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
    643 #define	bus_dmamap_load_uio(t, m, u, f)				\
    644 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
    645 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
    646 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
    647 #define	bus_dmamap_unload(t, p)					\
    648 	(*(t)->_dmamap_unload)((t), (p))
    649 #define	bus_dmamap_sync(t, p, o, l, ops)			\
    650 	(*(t)->_dmamap_sync)((t), (p), (o), (l), (ops))
    651 
    652 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
    653 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
    654 #define	bus_dmamem_free(t, sg, n)				\
    655 	(*(t)->_dmamem_free)((t), (sg), (n))
    656 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
    657 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
    658 #define	bus_dmamem_unmap(t, k, s)				\
    659 	(*(t)->_dmamem_unmap)((t), (k), (s))
    660 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
    661 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
    662 
    663 /*
    664  *	bus_dmamap_t
    665  *
    666  *	Describes a DMA mapping.
    667  */
    668 struct hpcmips_bus_dmamap {
    669 	/*
    670 	 * PRIVATE MEMBERS: not for use my machine-independent code.
    671 	 */
    672 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
    673 	int		_dm_segcnt;	/* number of segs this map can map */
    674 	bus_size_t	_dm_maxsegsz;	/* largest possible segment */
    675 	bus_size_t	_dm_boundary;	/* don't cross this */
    676 	int		_dm_flags;	/* misc. flags */
    677 
    678 	/*
    679 	 * PUBLIC MEMBERS: these are used by machine-independent code.
    680 	 */
    681 	bus_size_t	dm_mapsize;	/* size of the mapping */
    682 	int		dm_nsegs;	/* # valid segments in mapping */
    683 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
    684 };
    685 
    686 #ifdef _HPCMIPS_BUS_DMA_PRIVATE
    687 int	_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
    688 	    bus_size_t, int, bus_dmamap_t *));
    689 void	_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
    690 int	_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
    691 	    bus_size_t, struct proc *, int));
    692 int	_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
    693 	    struct mbuf *, int));
    694 int	_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
    695 	    struct uio *, int));
    696 int	_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
    697 	    bus_dma_segment_t *, int, bus_size_t, int));
    698 void	_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
    699 void	_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
    700 	    bus_size_t, int));
    701 
    702 int	_bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
    703 	    bus_size_t alignment, bus_size_t boundary,
    704 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
    705 void	_bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
    706 	    int nsegs));
    707 int	_bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
    708 	    int nsegs, size_t size, caddr_t *kvap, int flags));
    709 void	_bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
    710 	    size_t size));
    711 paddr_t	_bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
    712 	    int nsegs, off_t off, int prot, int flags));
    713 
    714 int	_bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
    715 	    bus_size_t alignment, bus_size_t boundary,
    716 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
    717 	    vaddr_t low, vaddr_t high));
    718 
    719 extern struct hpcmips_bus_dma_tag hpcmips_default_bus_dma_tag;
    720 #endif /* _HPCMIPS_BUS_DMA_PRIVATE */
    721 
    722 #endif /* _HPCMIPS_BUS_H_ */
    723