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