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