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