Home | History | Annotate | Line # | Download | only in include
bus.h revision 1.3
      1 /*	$NetBSD: bus.h,v 1.3 1999/03/23 21:29:06 drochner Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 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 /*
     41  * bus_space(9) and bus_dma(9) interface for NetBSD/x68k.
     42  */
     43 
     44 #ifndef _X68K_BUS_H_
     45 #define _X68K_BUS_H_
     46 
     47 /*
     48  * Bus address and size types
     49  */
     50 typedef u_long	bus_addr_t;
     51 typedef u_long	bus_size_t;
     52 typedef	u_long	bus_space_handle_t;
     53 
     54 /*
     55  * Bus space descripter
     56  */
     57 typedef struct x68k_bus_space *bus_space_tag_t;
     58 
     59 struct x68k_bus_space {
     60 #if 0
     61 	enum {
     62 		X68K_INTIO_BUS,
     63 		X68K_PCI_BUS,
     64 		X68K_NEPTUNE_BUS
     65 	}	x68k_bus_type;
     66 #endif
     67 
     68 	int	(*x68k_bus_space_map) __P((
     69 				bus_space_tag_t,
     70 				bus_addr_t,
     71 				bus_size_t,
     72 				int,			/* flags */
     73 				bus_space_handle_t *));
     74 	void	(*x68k_bus_space_unmap) __P((
     75 				bus_space_tag_t,
     76 				bus_space_handle_t,
     77 				bus_size_t));
     78 	int	(*x68k_bus_space_subregion) __P((
     79 				bus_space_tag_t,
     80 				bus_space_handle_t,
     81 				bus_size_t,		/* offset */
     82 				bus_size_t,		/* size */
     83 				bus_space_handle_t *));
     84 
     85 	int	(*x68k_bus_space_alloc) __P((
     86 				bus_space_tag_t,
     87 				bus_addr_t,		/* reg_start */
     88 				bus_addr_t,		/* reg_end */
     89 				bus_size_t,
     90 				bus_size_t,		/* alignment */
     91 				bus_size_t,		/* boundary */
     92 				int,			/* flags */
     93 				bus_addr_t *,
     94 				bus_space_handle_t *));
     95 	void	(*x68k_bus_space_free) __P((
     96 				bus_space_tag_t,
     97 				bus_space_handle_t,
     98 				bus_size_t));
     99 
    100 #if 0
    101 	void	(*x68k_bus_space_barrier) __P((
    102 				bus_space_tag_t,
    103 				bus_space_handle_t,
    104 				bus_size_t,		/* offset */
    105 				bus_size_t,		/* length */
    106 				int));			/* flags */
    107 #endif
    108 
    109 	struct device *x68k_bus_device;
    110 };
    111 
    112 int x68k_bus_space_alloc __P((bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t, bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *));
    113 void x68k_bus_space_free __P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
    114 
    115 /*
    116  * bus_space(9) interface
    117  */
    118 
    119 #define bus_space_map(t,a,s,f,h) \
    120 		((*((t)->x68k_bus_space_map)) ((t),(a),(s),(f),(h)))
    121 #define bus_space_unmap(t,h,s) \
    122 		((*((t)->x68k_bus_space_unmap)) ((t),(h),(s)))
    123 #define bus_space_subregion(t,h,o,s,p) \
    124 		((*((t)->x68k_bus_space_subregion)) ((t),(h),(o),(s),(p)))
    125 #define BUS_SPACE_MAP_CACHEABLE	0x0001
    126 #define BUS_SPACE_MAP_LINEAR	0x0002
    127 /*
    128  * For simpler hadware, many x68k devices are mapped with shifted address
    129  * i.e. only on even or odd addresses.
    130  */
    131 #define BUS_SPACE_MAP_SHIFTED	0x1001
    132 
    133 #define bus_space_alloc(t,rs,re,s,a,b,f,r,h) \
    134 		((*((t)->x68k_bus_space_alloc)) ((t),(rs),(re),(s),(a),(b),(f),(r),(h)))
    135 #define bus_space_free(t,h,s) \
    136 		((*((t)->x68k_bus_space_free)) ((t),(h),(s)))
    137 
    138 /*
    139  * Note: the 680x0 does not currently require barriers, but we must
    140  * provide the flags to MI code.
    141  */
    142 #define	bus_space_barrier(t, h, o, l, f)	\
    143 	((void)((void)(t), (void)(h), (void)(o), (void)(l), (void)(f)))
    144 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
    145 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
    146 
    147 #define bus_space_read_1(t,h,o) _bus_space_read_1(t,h,o)
    148 #define bus_space_read_2(t,h,o) _bus_space_read_2(t,h,o)
    149 #define bus_space_read_4(t,h,o) _bus_space_read_4(t,h,o)
    150 
    151 #define bus_space_read_multi_1(t,h,o,p,c) _bus_space_read_multi_1(t,h,o,p,c)
    152 #define bus_space_read_multi_2(t,h,o,p,c) _bus_space_read_multi_2(t,h,o,p,c)
    153 #define bus_space_read_multi_4(t,h,o,p,c) _bus_space_read_multi_4(t,h,o,p,c)
    154 
    155 #define bus_space_read_region_1(t,h,o,p,c) _bus_space_read_region_1(t,h,o,p,c)
    156 #define bus_space_read_region_2(t,h,o,p,c) _bus_space_read_region_2(t,h,o,p,c)
    157 #define bus_space_read_region_4(t,h,o,p,c) _bus_space_read_region_4(t,h,o,p,c)
    158 
    159 #define bus_space_write_1(t,h,o,v) _bus_space_write_1(t,h,o,v)
    160 #define bus_space_write_2(t,h,o,v) _bus_space_write_2(t,h,o,v)
    161 #define bus_space_write_4(t,h,o,v) _bus_space_write_4(t,h,o,v)
    162 
    163 #define bus_space_write_multi_1(t,h,o,p,c) _bus_space_write_multi_1(t,h,o,p,c)
    164 #define bus_space_write_multi_2(t,h,o,p,c) _bus_space_write_multi_2(t,h,o,p,c)
    165 #define bus_space_write_multi_4(t,h,o,p,c) _bus_space_write_multi_4(t,h,o,p,c)
    166 
    167 #define bus_space_write_region_1(t,h,o,p,c) \
    168 		_bus_space_write_region_1(t,h,o,p,c)
    169 #define bus_space_write_region_2(t,h,o,p,c) \
    170 		_bus_space_write_region_2(t,h,o,p,c)
    171 #define bus_space_write_region_4(t,h,o,p,c) \
    172 		_bus_space_write_region_4(t,h,o,p,c)
    173 
    174 #define bus_space_set_region_1(t,h,o,v,c) _bus_space_set_region_1(t,h,o,v,c)
    175 #define bus_space_set_region_2(t,h,o,v,c) _bus_space_set_region_2(t,h,o,v,c)
    176 #define bus_space_set_region_4(t,h,o,v,c) _bus_space_set_region_4(t,h,o,v,c)
    177 
    178 #define bus_space_copy_region_1(t,sh,so,dh,do,c) \
    179 		_bus_space_copy_region_1(t,sh,so,dh,do,c)
    180 #define bus_space_copy_region_2(t,sh,so,dh,do,c) \
    181 		_bus_space_copy_region_2(t,sh,so,dh,do,c)
    182 #define bus_space_copy_region_4(t,sh,so,dh,do,c) \
    183 		_bus_space_copy_region_4(t,sh,so,dh,do,c)
    184 
    185 static inline u_int8_t _bus_space_read_1
    186 	__P((bus_space_tag_t, bus_space_handle_t bsh, bus_size_t offset));
    187 static inline u_int16_t _bus_space_read_2
    188 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
    189 static inline u_int32_t _bus_space_read_4
    190 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t));
    191 
    192 static inline void _bus_space_read_multi_1
    193 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    194 	     u_int8_t *, bus_size_t));
    195 static inline void _bus_space_read_multi_2
    196 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    197 	     u_int16_t *, bus_size_t));
    198 static inline void _bus_space_read_multi_4
    199 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    200 	     u_int32_t *, bus_size_t));
    201 
    202 static inline void _bus_space_read_region_1
    203 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    204 	     u_int8_t *, bus_size_t));
    205 static inline void _bus_space_read_region_2
    206 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    207 	     u_int16_t *, bus_size_t));
    208 static inline void _bus_space_read_region_4
    209 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    210 	     u_int32_t *, bus_size_t));
    211 
    212 static inline void _bus_space_write_1
    213 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t));
    214 static inline void _bus_space_write_2
    215 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t));
    216 static inline void _bus_space_write_4
    217 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t));
    218 
    219 static inline void _bus_space_write_multi_1
    220 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    221 	     u_int8_t *, bus_size_t));
    222 static inline void _bus_space_write_multi_2
    223 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    224 	     u_int16_t *, bus_size_t));
    225 static inline void _bus_space_write_multi_4
    226 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    227 	     u_int32_t *, bus_size_t));
    228 
    229 static inline void _bus_space_write_region_1
    230 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    231 	     u_int8_t *, bus_size_t));
    232 static inline void _bus_space_write_region_2
    233 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    234 	     u_int16_t *, bus_size_t));
    235 static inline void _bus_space_write_region_4
    236 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    237 	     u_int32_t *, bus_size_t));
    238 
    239 static inline void _bus_space_set_region_1
    240 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    241 	     u_int8_t, bus_size_t));
    242 static inline void _bus_space_set_region_2
    243 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    244 	     u_int16_t, bus_size_t));
    245 static inline void _bus_space_set_region_4
    246 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    247 	     u_int32_t, bus_size_t));
    248 
    249 static inline void _bus_space_copy_region_1
    250 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    251 	     bus_space_handle_t, bus_size_t, bus_size_t));
    252 static inline void _bus_space_copy_region_2
    253 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    254 	     bus_space_handle_t, bus_size_t, bus_size_t));
    255 static inline void _bus_space_copy_region_4
    256 	__P((bus_space_tag_t, bus_space_handle_t, bus_size_t,
    257 	     bus_space_handle_t, bus_size_t, bus_size_t));
    258 
    259 
    260 static inline u_int8_t
    261 _bus_space_read_1(t, bsh, offset)
    262 	bus_space_tag_t t;
    263 	bus_space_handle_t bsh;
    264 	bus_size_t offset;
    265 {
    266 	return (*((volatile u_int8_t *) ((bsh&0x80000000)
    267 					 ? (bsh&0x7fffffff) + offset*2
    268 					 : bsh + offset)));
    269 }
    270 
    271 static inline u_int16_t
    272 _bus_space_read_2(t, bsh, offset)
    273 	bus_space_tag_t t;
    274 	bus_space_handle_t bsh;
    275 	bus_size_t offset;
    276 {
    277 	return (*((volatile u_int16_t *) ((bsh&0x80000000)
    278 					  ? (bsh&0x7fffffff) + offset*2
    279 					  : bsh + offset)));
    280 }
    281 
    282 static inline u_int32_t
    283 _bus_space_read_4(t, bsh, offset)
    284 	bus_space_tag_t t;
    285 	bus_space_handle_t bsh;
    286 	bus_size_t offset;
    287 {
    288 	return (*((volatile u_int32_t *) ((bsh&0x80000000)
    289 					  ? (bsh&0x7fffffff) + offset*2
    290 					  : bsh + offset)));
    291 }
    292 
    293 static inline void
    294 _bus_space_read_multi_1(t, bsh, offset, datap, count)
    295 	bus_space_tag_t t;
    296 	bus_space_handle_t bsh;
    297 	bus_size_t offset;
    298 	u_int8_t *datap;
    299 	bus_size_t count;
    300 {
    301 	while (count-- > 0) {
    302 		*datap++ = *(volatile u_int8_t *) ((bsh&0x80000000)
    303 						   ? ((bsh&0x7fffffff)
    304 						      + offset*2)
    305 						   : bsh + offset);
    306 	}
    307 }
    308 
    309 static inline void
    310 _bus_space_read_multi_2(t, bsh, offset, datap, count)
    311 	bus_space_tag_t t;
    312 	bus_space_handle_t bsh;
    313 	bus_size_t offset;
    314 	u_int16_t *datap;
    315 	bus_size_t count;
    316 {
    317 	while (count-- > 0) {
    318 		*datap++ = *(volatile u_int16_t *) ((bsh&0x80000000)
    319 						    ? ((bsh&0x7fffffff)
    320 						       + offset*2)
    321 						    : bsh + offset);
    322 	}
    323 }
    324 
    325 static inline void
    326 _bus_space_read_multi_4(t, bsh, offset, datap, count)
    327 	bus_space_tag_t t;
    328 	bus_space_handle_t bsh;
    329 	bus_size_t offset;
    330 	u_int32_t *datap;
    331 	bus_size_t count;
    332 {
    333 	while (count-- > 0) {
    334 		*datap++ = *(volatile u_int32_t *) ((bsh&0x80000000)
    335 						    ? ((bsh&0x7fffffff)
    336 						       + offset*2)
    337 						    : bsh + offset);
    338 	}
    339 }
    340 
    341 static inline void
    342 _bus_space_read_region_1(t, bsh, offset, datap, count)
    343 	bus_space_tag_t t;
    344 	bus_space_handle_t bsh;
    345 	bus_size_t offset;
    346 	u_int8_t *datap;
    347 	bus_size_t count;
    348 {
    349 	volatile u_int8_t *addr = (void *) ((bsh&0x80000000)
    350 					    ? (bsh&0x7fffffff) + offset*2
    351 					    : bsh + offset);
    352 
    353 	while (count-- > 0) {
    354 		*datap++ = *addr++;
    355 	}
    356 }
    357 
    358 static inline void
    359 _bus_space_read_region_2(t, bsh, offset, datap, count)
    360 	bus_space_tag_t t;
    361 	bus_space_handle_t bsh;
    362 	bus_size_t offset;
    363 	u_int16_t *datap;
    364 	bus_size_t count;
    365 {
    366 	volatile u_int16_t *addr = (void *) ((bsh&0x80000000)
    367 					     ? (bsh&0x7fffffff) + offset*2
    368 					     : bsh + offset);
    369 
    370 	while (count-- > 0) {
    371 		*datap++ = *addr++;
    372 	}
    373 }
    374 
    375 static inline void
    376 _bus_space_read_region_4(t, bsh, offset, datap, count)
    377 	bus_space_tag_t t;
    378 	bus_space_handle_t bsh;
    379 	bus_size_t offset;
    380 	u_int32_t *datap;
    381 	bus_size_t count;
    382 {
    383 	volatile u_int32_t *addr = (void *) ((bsh&0x80000000)
    384 					     ? (bsh&0x7fffffff) + offset*2
    385 					     : bsh + offset);
    386 
    387 	while (count-- > 0) {
    388 		*datap++ = *addr++;
    389 	}
    390 }
    391 
    392 static inline void
    393 _bus_space_write_1(t, bsh, offset, value)
    394 	bus_space_tag_t t;
    395 	bus_space_handle_t bsh;
    396 	bus_size_t offset;
    397 	u_int8_t value;
    398 {
    399 	*(volatile u_int8_t *) ((bsh&0x80000000)
    400 				? (bsh&0x7fffffff) + offset*2
    401 				: bsh + offset) = value;
    402 }
    403 
    404 static inline void
    405 _bus_space_write_2(t, bsh, offset, value)
    406 	bus_space_tag_t t;
    407 	bus_space_handle_t bsh;
    408 	bus_size_t offset;
    409 	u_int16_t value;
    410 {
    411 	*(volatile u_int16_t *) ((bsh&0x80000000)
    412 				 ? (bsh&0x7fffffff) + offset*2
    413 				 : bsh + offset) = value;
    414 }
    415 
    416 static inline void
    417 _bus_space_write_4(t, bsh, offset, value)
    418 	bus_space_tag_t t;
    419 	bus_space_handle_t bsh;
    420 	bus_size_t offset;
    421 	u_int32_t value;
    422 {
    423 	*(volatile u_int32_t *) ((bsh&0x80000000)
    424 				 ? (bsh&0x7fffffff) + offset*2
    425 				 : bsh + offset) = value;
    426 }
    427 
    428 static inline void
    429 _bus_space_write_multi_1(t, bsh, offset, datap, count)
    430 	bus_space_tag_t t;
    431 	bus_space_handle_t bsh;
    432 	bus_size_t offset;
    433 	u_int8_t *datap;
    434 	bus_size_t count;
    435 {
    436 	while (count-- > 0) {
    437 		*(volatile u_int8_t *) ((bsh&0x80000000)
    438 					? (bsh&0x7fffffff) + offset*2
    439 					: bsh + offset) = *datap++;
    440 	}
    441 }
    442 
    443 static inline void
    444 _bus_space_write_multi_2(t, bsh, offset, datap, count)
    445 	bus_space_tag_t t;
    446 	bus_space_handle_t bsh;
    447 	bus_size_t offset;
    448 	u_int16_t *datap;
    449 	bus_size_t count;
    450 {
    451 	while (count-- > 0) {
    452 		*(volatile u_int16_t *) ((bsh&0x80000000)
    453 					 ? (bsh&0x7fffffff) + offset*2
    454 					 : bsh + offset) = *datap++;
    455 	}
    456 }
    457 
    458 static inline void
    459 _bus_space_write_multi_4(t, bsh, offset, datap, count)
    460 	bus_space_tag_t t;
    461 	bus_space_handle_t bsh;
    462 	bus_size_t offset;
    463 	u_int32_t *datap;
    464 	bus_size_t count;
    465 {
    466 	while (count-- > 0) {
    467 		*(volatile u_int32_t *) ((bsh&0x80000000)
    468 					 ? (bsh&0x7fffffff) + offset*2
    469 					 : bsh + offset) = *datap++;
    470 	}
    471 }
    472 
    473 static inline void
    474 _bus_space_write_region_1(t, bsh, offset, datap, count)
    475 	bus_space_tag_t t;
    476 	bus_space_handle_t bsh;
    477 	bus_size_t offset;
    478 	u_int8_t *datap;
    479 	bus_size_t count;
    480 {
    481 	volatile u_int8_t *addr = (void *) ((bsh&0x80000000)
    482 					    ? (bsh&0x7fffffff) + offset*2
    483 					    : bsh + offset);
    484 
    485 	while (count-- > 0) {
    486 		*addr++ = *datap++;
    487 	}
    488 }
    489 
    490 static inline void
    491 _bus_space_write_region_2(t, bsh, offset, datap, count)
    492 	bus_space_tag_t t;
    493 	bus_space_handle_t bsh;
    494 	bus_size_t offset;
    495 	u_int16_t *datap;
    496 	bus_size_t count;
    497 {
    498 	volatile u_int16_t *addr = (void *) ((bsh&0x80000000)
    499 					     ? (bsh&0x7fffffff) + offset*2
    500 					     : bsh + offset);
    501 
    502 	while (count-- > 0) {
    503 		*addr++ = *datap++;
    504 	}
    505 }
    506 
    507 static inline void
    508 _bus_space_write_region_4(t, bsh, offset, datap, count)
    509 	bus_space_tag_t t;
    510 	bus_space_handle_t bsh;
    511 	bus_size_t offset;
    512 	u_int32_t *datap;
    513 	bus_size_t count;
    514 {
    515 	volatile u_int32_t *addr = (void *) ((bsh&0x80000000)
    516 					     ? (bsh&0x7fffffff) + offset*2
    517 					     : bsh + offset);
    518 
    519 	while (count-- > 0) {
    520 		*addr++ = *datap++;
    521 	}
    522 }
    523 
    524 static inline void
    525 _bus_space_set_region_1(t, bsh, offset, value, count)
    526 	bus_space_tag_t t;
    527 	bus_space_handle_t bsh;
    528 	bus_size_t offset;
    529 	u_int8_t value;
    530 	bus_size_t count;
    531 {
    532 	volatile u_int8_t *addr = (void *) ((bsh&0x80000000)
    533 					    ? (bsh&0x7fffffff) + offset*2
    534 					    : bsh + offset);
    535 
    536 	while (count-- > 0) {
    537 		*addr++ = value;
    538 	}
    539 }
    540 
    541 static inline void
    542 _bus_space_set_region_2(t, bsh, offset, value, count)
    543 	bus_space_tag_t t;
    544 	bus_space_handle_t bsh;
    545 	bus_size_t offset;
    546 	u_int16_t value;
    547 	bus_size_t count;
    548 {
    549 	volatile u_int16_t *addr = (void *) ((bsh&0x80000000)
    550 					     ? (bsh&0x7fffffff) + offset*2
    551 					     : bsh + offset);
    552 
    553 	while (count-- > 0) {
    554 		*addr++ = value;
    555 	}
    556 }
    557 
    558 static inline void
    559 _bus_space_set_region_4(t, bsh, offset, value, count)
    560 	bus_space_tag_t t;
    561 	bus_space_handle_t bsh;
    562 	bus_size_t offset;
    563 	u_int32_t value;
    564 	bus_size_t count;
    565 {
    566 	volatile u_int32_t *addr = (void *) ((bsh&0x80000000)
    567 					     ? (bsh&0x7fffffff) + offset*2
    568 					     : bsh + offset);
    569 
    570 	while (count-- > 0) {
    571 		*addr++ = value;
    572 	}
    573 }
    574 
    575 static inline void
    576 _bus_space_copy_region_1(t, sbsh, soffset, dbsh, doffset, count)
    577 	bus_space_tag_t t;
    578 	bus_space_handle_t sbsh;
    579 	bus_size_t soffset;
    580 	bus_space_handle_t dbsh;
    581 	bus_size_t doffset;
    582 	bus_size_t count;
    583 {
    584 	volatile u_int8_t *saddr = (void *) (sbsh + soffset);
    585 	volatile u_int8_t *daddr = (void *) (dbsh + doffset);
    586 
    587 	if ((u_int32_t) saddr >= (u_int32_t) daddr)
    588 		while (count-- > 0)
    589 			*daddr++ = *saddr++;
    590 	else {
    591 		saddr += count;
    592 		daddr += count;
    593 		while (count-- > 0)
    594 			*--daddr = *--saddr;
    595 	}
    596 }
    597 
    598 static inline void
    599 _bus_space_copy_region_2(t, sbsh, soffset, dbsh, doffset, count)
    600 	bus_space_tag_t t;
    601 	bus_space_handle_t sbsh;
    602 	bus_size_t soffset;
    603 	bus_space_handle_t dbsh;
    604 	bus_size_t doffset;
    605 	bus_size_t count;
    606 {
    607 	volatile u_int16_t *saddr = (void *) (sbsh + soffset);
    608 	volatile u_int16_t *daddr = (void *) (dbsh + doffset);
    609 
    610 	if ((u_int32_t) saddr >= (u_int32_t) daddr)
    611 		while (count-- > 0)
    612 			*daddr++ = *saddr++;
    613 	else {
    614 		saddr += count;
    615 		daddr += count;
    616 		while (count-- > 0)
    617 			*--daddr = *--saddr;
    618 	}
    619 }
    620 
    621 static inline void
    622 _bus_space_copy_region_4(t, sbsh, soffset, dbsh, doffset, count)
    623 	bus_space_tag_t t;
    624 	bus_space_handle_t sbsh;
    625 	bus_size_t soffset;
    626 	bus_space_handle_t dbsh;
    627 	bus_size_t doffset;
    628 	bus_size_t count;
    629 {
    630 	volatile u_int32_t *saddr = (void *) (sbsh + soffset);
    631 	volatile u_int32_t *daddr = (void *) (dbsh + doffset);
    632 
    633 	if ((u_int32_t) saddr >= (u_int32_t) daddr)
    634 		while (count-- > 0)
    635 			*daddr++ = *saddr++;
    636 	else {
    637 		saddr += count;
    638 		daddr += count;
    639 		while (count-- > 0)
    640 			*--daddr = *--saddr;
    641 	}
    642 }
    643 
    644 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
    645 
    646 /*
    647  * DMA segment
    648  */
    649 struct x68k_bus_dma_segment {
    650 	bus_addr_t	ds_addr;
    651 	bus_size_t	ds_len;
    652 };
    653 typedef struct x68k_bus_dma_segment	bus_dma_segment_t;
    654 
    655 /*
    656  * DMA descriptor
    657  */
    658 /* Forwards needed by prototypes below. */
    659 struct mbuf;
    660 struct uio;
    661 
    662 typedef struct x68k_bus_dma		*bus_dma_tag_t;
    663 typedef struct x68k_bus_dmamap		*bus_dmamap_t;
    664 struct x68k_bus_dma {
    665 	/*
    666 	 * The `bounce threshold' is checked while we are loading
    667 	 * the DMA map.  If the physical address of the segment
    668 	 * exceeds the threshold, an error will be returned.  The
    669 	 * caller can then take whatever action is necessary to
    670 	 * bounce the transfer.  If this value is 0, it will be
    671 	 * ignored.
    672 	 */
    673 	bus_addr_t _bounce_thresh;
    674 
    675 	/*
    676 	 * DMA mapping methods.
    677 	 */
    678 	int	(*x68k_dmamap_create) __P((bus_dma_tag_t, bus_size_t, int,
    679 		    bus_size_t, bus_size_t, int, bus_dmamap_t *));
    680 	void	(*x68k_dmamap_destroy) __P((bus_dma_tag_t, bus_dmamap_t));
    681 	int	(*x68k_dmamap_load) __P((bus_dma_tag_t, bus_dmamap_t, void *,
    682 		    bus_size_t, struct proc *, int));
    683 	int	(*x68k_dmamap_load_mbuf) __P((bus_dma_tag_t, bus_dmamap_t,
    684 		    struct mbuf *, int));
    685 	int	(*x68k_dmamap_load_uio) __P((bus_dma_tag_t, bus_dmamap_t,
    686 		    struct uio *, int));
    687 	int	(*x68k_dmamap_load_raw) __P((bus_dma_tag_t, bus_dmamap_t,
    688 		    bus_dma_segment_t *, int, bus_size_t, int));
    689 	void	(*x68k_dmamap_unload) __P((bus_dma_tag_t, bus_dmamap_t));
    690 	void	(*x68k_dmamap_sync) __P((bus_dma_tag_t, bus_dmamap_t,
    691 		    bus_addr_t, bus_size_t, int));
    692 
    693 	/*
    694 	 * DMA memory utility functions.
    695 	 */
    696 	int	(*x68k_dmamem_alloc) __P((bus_dma_tag_t, bus_size_t, bus_size_t,
    697 		    bus_size_t, bus_dma_segment_t *, int, int *, int));
    698 	void	(*x68k_dmamem_free) __P((bus_dma_tag_t,
    699 		    bus_dma_segment_t *, int));
    700 	int	(*x68k_dmamem_map) __P((bus_dma_tag_t, bus_dma_segment_t *,
    701 		    int, size_t, caddr_t *, int));
    702 	void	(*x68k_dmamem_unmap) __P((bus_dma_tag_t, caddr_t, size_t));
    703 	int	(*x68k_dmamem_mmap) __P((bus_dma_tag_t, bus_dma_segment_t *,
    704 		    int, int, int, int));
    705 };
    706 
    707 /*
    708  *	bus_dmamap_t
    709  *
    710  *	Describes a DMA mapping.
    711  */
    712 struct x68k_bus_dmamap {
    713 	/*
    714 	 * PRIVATE MEMBERS: not for use my machine-independent code.
    715 	 */
    716 	bus_size_t	x68k_dm_size;	/* largest DMA transfer mappable */
    717 	int		x68k_dm_segcnt;	/* number of segs this map can map */
    718 	bus_size_t	x68k_dm_maxsegsz; /* largest possible segment */
    719 	bus_size_t	x68k_dm_boundary; /* don't cross this */
    720 	bus_addr_t	x68k_dm_bounce_thresh; /* bounce threshold */
    721 	int		x68k_dm_flags;	/* misc. flags */
    722 
    723 	void		*x68k_dm_cookie; /* cookie for bus-specific functions */
    724 
    725 	/*
    726 	 * PUBLIC MEMBERS: these are used by machine-independent code.
    727 	 */
    728 	bus_size_t	dm_mapsize;	/* size of the mapping */
    729 	int		dm_nsegs;	/* # valid segments in mapping */
    730 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
    731 };
    732 
    733 int	x68k_bus_dmamap_create __P((bus_dma_tag_t, bus_size_t, int, bus_size_t,
    734 	    bus_size_t, int, bus_dmamap_t *));
    735 void	x68k_bus_dmamap_destroy __P((bus_dma_tag_t, bus_dmamap_t));
    736 int	x68k_bus_dmamap_load __P((bus_dma_tag_t, bus_dmamap_t, void *,
    737 	    bus_size_t, struct proc *, int));
    738 int	x68k_bus_dmamap_load_mbuf __P((bus_dma_tag_t, bus_dmamap_t,
    739 	    struct mbuf *, int));
    740 int	x68k_bus_dmamap_load_uio __P((bus_dma_tag_t, bus_dmamap_t,
    741 	    struct uio *, int));
    742 int	x68k_bus_dmamap_load_raw __P((bus_dma_tag_t, bus_dmamap_t,
    743 	    bus_dma_segment_t *, int, bus_size_t, int));
    744 void	x68k_bus_dmamap_unload __P((bus_dma_tag_t, bus_dmamap_t));
    745 void	x68k_bus_dmamap_sync __P((bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
    746 	    bus_size_t, int));
    747 
    748 int	x68k_bus_dmamem_alloc __P((bus_dma_tag_t tag, bus_size_t size,
    749 	    bus_size_t alignment, bus_size_t boundary,
    750 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags));
    751 void	x68k_bus_dmamem_free __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
    752 	    int nsegs));
    753 int	x68k_bus_dmamem_map __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
    754 	    int nsegs, size_t size, caddr_t *kvap, int flags));
    755 void	x68k_bus_dmamem_unmap __P((bus_dma_tag_t tag, caddr_t kva,
    756 	    size_t size));
    757 int	x68k_bus_dmamem_mmap __P((bus_dma_tag_t tag, bus_dma_segment_t *segs,
    758 	    int nsegs, int off, int prot, int flags));
    759 
    760 int	x68k_bus_dmamap_load_buffer __P((bus_dmamap_t, void *,
    761 	    bus_size_t buflen, struct proc *, int, paddr_t *, int *, int));
    762 int	x68k_bus_dmamem_alloc_range __P((bus_dma_tag_t tag, bus_size_t size,
    763 	    bus_size_t alignment, bus_size_t boundary,
    764 	    bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
    765 	    paddr_t low, paddr_t high));
    766 
    767 #define	bus_dmamap_create(t,s,n,m,b,f,p) \
    768 	((*((t)->x68k_dmamap_create)) ((t),(s),(n),(m),(b),(f),(p)))
    769 #define	bus_dmamap_destroy(t,p) \
    770 	((*((t)->x68k_dmamap_destroy)) ((t),(p)))
    771 #define	bus_dmamap_load(t,m,b,s,p,f) \
    772 	((*((t)->x68k_dmamap_load)) ((t),(m),(b),(s),(p),(f)))
    773 #define	bus_dmamap_load_mbuf(t,m,b,f) \
    774 	((*((t)->x68k_dmamap_load_mbuf)) ((t),(m),(b),(f)))
    775 #define	bus_dmamap_load_uio(t,m,u,f) \
    776 	((*((t)->x68k_dmamap_load_uio)) ((t),(m),(u),(f)))
    777 #define	bus_dmamap_load_raw(t,m,sg,n,s,f) \
    778 	((*((t)->x68k_dmamap_load_raw)) ((t),(m),(sg),(n),(s),(f)))
    779 #define	bus_dmamap_unload(t,p) \
    780 	((*((t)->x68k_dmamap_unload)) ((t),(p)))
    781 #define	bus_dmamap_sync(t,p,o,l,ops) \
    782 	((*((t)->x68k_dmamap_sync)) ((t),(p),(o),(l),(ops)))
    783 
    784 #define	bus_dmamem_alloc(t,s,a,b,sg,n,r,f) \
    785 	((*((t)->x68k_dmamem_alloc)) ((t),(s),(a),(b),(sg),(n),(r),(f)))
    786 #define	bus_dmamem_free(t,sg,n) \
    787 	((*((t)->x68k_dmamem_free)) ((t),(sg),(n)))
    788 #define	bus_dmamem_map(t,sg,n,s,k,f) \
    789 	((*((t)->x68k_dmamem_map)) ((t),(sg),(n),(s),(k),(f)))
    790 #define	bus_dmamem_unmap(t,k,s) \
    791 	((*((t)->x68k_dmamem_unmap)) ((t),(k),(s)))
    792 #define	bus_dmamem_mmap(t,sg,n,o,p,f) \
    793 	((*((t)->x68k_dmamem_mmap)) ((t),(sg),(n),(o),(p),(f)))
    794 
    795 /*
    796  * Flags used in various bus DMA methods.
    797  */
    798 #define	BUS_DMA_WAITOK		0x00	/* safe to sleep (pseudo-flag) */
    799 #define	BUS_DMA_NOWAIT		0x01	/* not safe to sleep */
    800 #define	BUS_DMA_ALLOCNOW	0x02	/* perform resource allocation now */
    801 #define	BUS_DMA_COHERENT	0x04	/* hint: map memory DMA coherent */
    802 #define	BUS_DMA_BUS1		0x10	/* placeholders for bus functions... */
    803 #define	BUS_DMA_BUS2		0x20
    804 #define	BUS_DMA_BUS3		0x40
    805 #define	BUS_DMA_BUS4		0x80
    806 
    807 /*
    808  * Operations performed by bus_dmamap_sync().
    809  */
    810 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
    811 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
    812 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
    813 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
    814 
    815 #endif /* _X68K_BUS_H_ */
    816