Home | History | Annotate | Line # | Download | only in include
bus.h revision 1.1
      1 /*	$NetBSD: bus.h,v 1.1 2009/07/20 04:41:37 kiyohara Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1996, 1997, 1998, 2001 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9  * NASA Ames Research Center.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions and the following disclaimer.
     16  * 2. Redistributions in binary form must reproduce the above copyright
     17  *    notice, this list of conditions and the following disclaimer in the
     18  *    documentation and/or other materials provided with the distribution.
     19  * 3. All advertising materials mentioning features or use of this software
     20  *    must display the following acknowledgement:
     21  *	This product includes software developed by the NetBSD
     22  *	Foundation, Inc. and its contributors.
     23  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24  *    contributors may be used to endorse or promote products derived
     25  *    from this software without specific prior written permission.
     26  *
     27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37  * POSSIBILITY OF SUCH DAMAGE.
     38  */
     39 
     40 /*
     41  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
     42  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
     43  *
     44  * Redistribution and use in source and binary forms, with or without
     45  * modification, are permitted provided that the following conditions
     46  * are met:
     47  * 1. Redistributions of source code must retain the above copyright
     48  *    notice, this list of conditions and the following disclaimer.
     49  * 2. Redistributions in binary form must reproduce the above copyright
     50  *    notice, this list of conditions and the following disclaimer in the
     51  *    documentation and/or other materials provided with the distribution.
     52  * 3. All advertising materials mentioning features or use of this software
     53  *    must display the following acknowledgement:
     54  *      This product includes software developed by Christopher G. Demetriou
     55  *	for the NetBSD Project.
     56  * 4. The name of the author may not be used to endorse or promote products
     57  *    derived from this software without specific prior written permission
     58  *
     59  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     60  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     61  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     62  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     63  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     64  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     65  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     66  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     67  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     68  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     69  */
     70 
     71 #ifndef _IA64_BUS_H_
     72 #define _IA64_BUS_H_
     73 
     74 #include <sys/systm.h>
     75 
     76 #include <machine/cpufunc.h>
     77 #include <machine/vmparam.h>
     78 
     79 #ifdef BUS_SPACE_DEBUG
     80 /*
     81  * Macros for sanity-checking the aligned-ness of pointers passed to
     82  * bus space ops.  These are not strictly necessary on the x86, but
     83  * could lead to performance improvements, and help catch problems
     84  * with drivers that would creep up on other architectures.
     85  */
     86 #define	__BUS_SPACE_ALIGNED_ADDRESS(p, t)				\
     87 	((((u_long)(p)) & (sizeof(t)-1)) == 0)
     88 
     89 #define	__BUS_SPACE_ADDRESS_SANITY(p, t, d)				\
     90 ({									\
     91 	if (__BUS_SPACE_ALIGNED_ADDRESS((p), t) == 0) {			\
     92 		printf("%s 0x%lx not aligned to %d bytes %s:%d\n",	\
     93 		    d, (u_long)(p), sizeof(t), __FILE__, __LINE__);	\
     94 	}								\
     95 	(void) 0;							\
     96 })
     97 
     98 #define BUS_SPACE_ALIGNED_POINTER(p, t) __BUS_SPACE_ALIGNED_ADDRESS(p, t)
     99 #else
    100 #define	__BUS_SPACE_ADDRESS_SANITY(p,t,d)	(void) 0
    101 #define BUS_SPACE_ALIGNED_POINTER(p, t) ALIGNED_POINTER(p, t)
    102 #endif /* BUS_SPACE_DEBUG */
    103 
    104 /*
    105  * bus_space_map flags
    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 /*
    113  * Derived from x86 implementation, ia64 has both i/o and mem spaces
    114  * These values are for bus space tag.
    115  */
    116 #define IA64_BUS_SPACE_IO	 0	 /* space is i/o space */
    117 #define IA64_BUS_SPACE_MEM	 1	 /* space is mem space */
    118 
    119 #define __BUS_SPACE_HAS_STREAM_METHODS 1
    120 
    121 /*
    122  * Bus address and size types
    123  */
    124 typedef u_long bus_addr_t;
    125 typedef u_long bus_size_t;
    126 
    127 /*
    128  * Access methods for bus resources and address space.
    129  */
    130 typedef	int bus_space_tag_t;
    131 typedef	u_long bus_space_handle_t;
    132 
    133 /* map/unmap */
    134 
    135 int	ia64_bus_space_map(bus_space_tag_t, bus_addr_t,
    136 	    bus_size_t, int, bus_space_handle_t *);
    137 void	ia64_bus_space_unmap(bus_space_tag_t, bus_space_handle_t,
    138 	    bus_size_t);
    139 int	ia64_bus_space_subregion(bus_space_tag_t, bus_space_handle_t,
    140 	    bus_size_t, bus_size_t, bus_space_handle_t *);
    141 #define	bus_space_map(t, a, s, f, hp)					\
    142 	ia64_bus_space_map((t), (a), (s), (f), (hp))
    143 #define bus_space_unmap(t, h, s)					\
    144 	ia64_bus_space_unmap((t), (h), (s))
    145 #define bus_space_subregion(t, h, o, s, nhp)				\
    146 	ia64_bus_space_subregion((t), (h), (o), (s), (nhp))
    147 
    148 /* vaddr */
    149 
    150 #define bus_space_vaddr(t, h) \
    151 	((t) == IA64_BUS_SPACE_MEM ? (void *)(h) : (void *)0)
    152 
    153 /* map to user space */
    154 
    155 paddr_t	ia64_bus_space_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
    156 
    157 #define	bus_space_mmap(t, b, o, p, f)					\
    158 	ia64_bus_space_mmap((t), (b), (o), (p), (f))
    159 
    160 /* alloc/free */
    161 
    162 int	ia64_bus_space_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t,
    163 	    bus_size_t, bus_size_t, bus_size_t, int, bus_addr_t *,
    164 	    bus_space_handle_t *);
    165 void	ia64_bus_space_free(bus_space_tag_t, bus_space_handle_t, bus_size_t);
    166 
    167 #define bus_space_alloc(t, rs, re, s, a, b, f, ap, hp)			\
    168 	ia64_bus_space__alloc((t), (rs), (re), (s), (a), (b), (f), (ap), (hp))
    169 #define bus_space_free(t, h, s)						\
    170 	ia64_bus_space_free((t), (h), (s))
    171 
    172 /*
    173  *	uintN_t bus_space_read_N(bus_space_tag_t tag,
    174  *	    bus_space_handle_t bsh, bus_size_t offset);
    175  *
    176  * Read a 1, 2, 4, or 8 byte quantity from bus space
    177  * described by tag/handle/offset.
    178  */
    179 
    180 #define	bus_space_read_1(t, h, o)					\
    181 	((t) == IA64_BUS_SPACE_IO ? (inb((h) + (o))) :\
    182 	    (*(volatile uint8_t *)((h) + (o))))
    183 
    184 #define	bus_space_read_2(t, h, o)					\
    185 	 (__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr"),	\
    186 	  ((t) == IA64_BUS_SPACE_IO ? (inw((h) + (o))) :		\
    187 	    (*(volatile uint16_t *)((h) + (o)))))
    188 
    189 #define	bus_space_read_4(t, h, o)					\
    190 	 (__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr"),	\
    191 	  ((t) == IA64_BUS_SPACE_IO ? (inl((h) + (o))) :		\
    192 	    (*(volatile uint32_t *)((h) + (o)))))
    193 
    194 #define	bus_space_read_8(t, h, o)					\
    195 	 (__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr"),	\
    196 	  ((t) == IA64_BUS_SPACE_IO ?					\
    197 	    ({ printf("%s: can't read 8bytes from I/O space\n", __FUNCTION__); 0;}) : \
    198 	    (*(volatile uint64_t *)((h) + (o)))))
    199 
    200 #define bus_space_read_stream_1 bus_space_read_1
    201 #define bus_space_read_stream_2 bus_space_read_2
    202 #define bus_space_read_stream_4 bus_space_read_4
    203 #define bus_space_read_stream_8 bus_space_read_8
    204 
    205 /*
    206  *	void bus_space_read_multi_N(bus_space_tag_t tag,
    207  *	    bus_space_handle_t bsh, bus_size_t offset,
    208  *	    uintN_t *addr, size_t count);
    209  *
    210  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
    211  * described by tag/handle/offset and copy into buffer provided.
    212  */
    213 
    214 #define	bus_space_read_multi_1(t, h, o, ptr, cnt)			\
    215 do {									\
    216 	if ((t) == IA64_BUS_SPACE_IO) {					\
    217 		insb((h) + (o), (ptr), (cnt));				\
    218 	} else {							\
    219 		int __i;						\
    220 		volatile uint8_t *__p = (uint8_t *)((h) + (o));		\
    221 		uint8_t *__dst = (ptr);					\
    222 		for (__i = 0; __i < (cnt); __i++)			\
    223 			*__dst++ = *__p;				\
    224 	}								\
    225 } while (/* CONSTCOND */ 0)
    226 
    227 #define	bus_space_read_multi_2(t, h, o, ptr, cnt)			\
    228 do {									\
    229 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint16_t, "buffer");		\
    230 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr");	\
    231 	if ((t) == IA64_BUS_SPACE_IO) {					\
    232 		insw((h) + (o), (ptr), (cnt));				\
    233 	} else {							\
    234 		int __i;						\
    235 		volatile uint16_t *__p = (uint16_t *)((h) + (o));	\
    236 		uint16_t *__dst = (ptr);				\
    237 		for (__i = 0; __i < (cnt); __i++)			\
    238 			*__dst++ = *__p;				\
    239 	}								\
    240 } while (/* CONSTCOND */ 0)
    241 
    242 #define	bus_space_read_multi_4(t, h, o, ptr, cnt)			\
    243 do {									\
    244 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint32_t, "buffer");		\
    245 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr");	\
    246 	if ((t) == IA64_BUS_SPACE_IO) {					\
    247 		insl((h) + (o), (ptr), (cnt));				\
    248 	} else {							\
    249 		int __i;						\
    250 		volatile uint32_t *__p = (uint32_t *)((h) + (o));	\
    251 		uint32_t *__dst = (ptr);				\
    252 		for (__i = 0; __i < (cnt); __i++)			\
    253 			*__dst++ = *__p;				\
    254 	}								\
    255 } while (/* CONSTCOND */ 0)
    256 
    257 #define	bus_space_read_multi_8(t, h, o, ptr, cnt)			\
    258 do {									\
    259 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint64_t, "buffer");		\
    260 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr");	\
    261 	if ((t) == IA64_BUS_SPACE_IO) {					\
    262 		printf("%s: can't read 8bytes from I/O space\n",	\
    263 		    __FUNCTION__);					\
    264 	} else {							\
    265 		int __i;						\
    266 		volatile uint64_t *__p = (uint64_t *)((h) + (o));	\
    267 		uint64_t *__dst = (ptr);				\
    268 		for (__i = 0; __i < (cnt); __i++)			\
    269 			*__dst++ = *__p;				\
    270 	}								\
    271 } while (/* CONSTCOND */ 0)
    272 
    273 #define bus_space_read_multi_stream_1 bus_space_read_multi_1
    274 #define bus_space_read_multi_stream_2 bus_space_read_multi_2
    275 #define bus_space_read_multi_stream_4 bus_space_read_multi_4
    276 #define bus_space_read_multi_stream_8 bus_space_read_multi_8
    277 
    278 
    279 /*
    280  *	void bus_space_read_region_N(bus_space_tag_t tag,
    281  *	    bus_space_handle_t bsh, bus_size_t offset,
    282  *	    uintN_t *addr, size_t count);
    283  *
    284  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
    285  * described by tag/handle and starting at `offset' and copy into
    286  * buffer provided.
    287  */
    288 
    289 #define	bus_space_read_region_1(t, h, o, ptr, cnt)			\
    290 do {									\
    291 	if ((t) == IA64_BUS_SPACE_IO) {					\
    292 		int __i;						\
    293 		volatile bus_addr_t __port = (h) + (o);			\
    294 		uint8_t *__dst = (ptr);					\
    295 		for (__i = 0; __i < (cnt); __i++) {			\
    296 			*__dst++ = inb(__port);				\
    297 			__port++;					\
    298 		}							\
    299 	} else {							\
    300 		int __i;						\
    301 		volatile uint8_t *__p = (uint8_t *)((h) + (o));		\
    302 		uint8_t *__dst = (ptr);					\
    303 		for (__i = 0; __i < (cnt); __i++)			\
    304 			*__dst++ = *__p++;				\
    305 	}								\
    306 } while (/* CONSTCOND */ 0)
    307 
    308 #define	bus_space_read_region_2(t, h, o, ptr, cnt)			\
    309 do {									\
    310 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint16_t, "buffer");		\
    311 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr");	\
    312 	if ((t) == IA64_BUS_SPACE_IO) {					\
    313 		int __i;						\
    314 		volatile bus_addr_t __port = (h) + (o);			\
    315 		uint8_t *__dst = (ptr);					\
    316 		for (__i = 0; __i < (cnt); __i++) {			\
    317 			*__dst++ = inb(__port);				\
    318 			__port += 2;					\
    319 		}							\
    320 	} else {							\
    321 		int __i;						\
    322 		volatile uint16_t *__p = (uint16_t *)((h) + (o));	\
    323 		uint16_t *__dst = (ptr);				\
    324 		for (__i = 0; __i < (cnt); __i++)			\
    325 			*__dst++ = *__p++;				\
    326 	}								\
    327 } while (/* CONSTCOND */ 0)
    328 
    329 #define	bus_space_read_region_4(t, h, o, ptr, cnt)			\
    330 do {									\
    331 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint32_t, "buffer");		\
    332 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr");	\
    333 	if ((t) == IA64_BUS_SPACE_IO) {					\
    334 		int __i;						\
    335 		volatile bus_addr_t __port = (h) + (o);			\
    336 		uint8_t *__dst = (ptr);					\
    337 		for (__i = 0; __i < (cnt); __i++) {			\
    338 			*__dst++ = inb(__port);				\
    339 			__port += 4;					\
    340 		}							\
    341 	} else {							\
    342 		volatile uint32_t *__p = (uint32_t *)((h) + (o));	\
    343 		uint32_t *__dst = (ptr);				\
    344 		for (__i = 0; __i < (cnt); __i++)			\
    345 			*__dst++ = *__p++;				\
    346 	}								\
    347 } while (/* CONSTCOND */ 0)
    348 
    349 #define	bus_space_read_region_8(t, h, o, ptr, cnt)			\
    350 do {									\
    351 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint64_t, "buffer");		\
    352 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr");	\
    353 	if ((t) == IA64_BUS_SPACE_IO) {					\
    354 		printf("%s: can't read 8bytes from I/O space\n",	\
    355 		    __FUNCTION__);					\
    356 	} else {							\
    357 		volatile uint64_t *__p = (uint64_t *)((h) + (o));	\
    358 		uint64_t *__dst = (ptr);				\
    359 		for (__i = 0; __i < (cnt); __i++)			\
    360 			*__dst++ = *__p++;				\
    361 	}								\
    362 } while (/* CONSTCOND */ 0)
    363 
    364 #define bus_space_read_region_stream_1 bus_space_read_region_1
    365 #define bus_space_read_region_stream_2 bus_space_read_region_2
    366 #define bus_space_read_region_stream_4 bus_space_read_region_4
    367 #define bus_space_read_region_stream_8 bus_space_read_region_8
    368 
    369 
    370 /*
    371  *	void bus_space_write_N(bus_space_tag_t tag,
    372  *	    bus_space_handle_t bsh, bus_size_t offset,
    373  *	    uintN_t value);
    374  *
    375  * Write the 1, 2, 4, or 8 byte value `value' to bus space
    376  * described by tag/handle/offset.
    377  */
    378 
    379 #define	bus_space_write_1(t, h, o, v)					\
    380 do {									\
    381 	if ((t) == IA64_BUS_SPACE_IO)					\
    382 		outb((h) + (o), (v));					\
    383 	else								\
    384 		((void)(*(volatile uint8_t *)((h) + (o)) = (v)));	\
    385 } while (/* CONSTCOND */ 0)
    386 
    387 #define	bus_space_write_2(t, h, o, v)					\
    388 do {									\
    389 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr");	\
    390 	if ((t) == IA64_BUS_SPACE_IO)					\
    391 		outw((h) + (o), (v));					\
    392 	else								\
    393 		((void)(*(volatile uint16_t *)((h) + (o)) = (v)));	\
    394 } while (/* CONSTCOND */ 0)
    395 
    396 #define	bus_space_write_4(t, h, o, v)					\
    397 do {									\
    398 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr");	\
    399 	if ((t) == IA64_BUS_SPACE_IO)					\
    400 		outl((h) + (o), (v));					\
    401 	else								\
    402 		((void)(*(volatile uint32_t *)((h) + (o)) = (v)));	\
    403 } while (/* CONSTCOND */ 0)
    404 
    405 #define	bus_space_write_8(t, h, o, v)					\
    406 	 __BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr");	\
    407 	 if ((t) == IA64_BUS_SPACE_IO ?					\
    408 	     printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__); : \
    409 	     (*(volatile uint64_t *)((h) + (o)) = (v)))
    410 
    411 #define bus_space_write_stream_1 bus_space_write_1
    412 #define bus_space_write_stream_2 bus_space_write_2
    413 #define bus_space_write_stream_4 bus_space_write_4
    414 #define bus_space_write_stream_8 bus_space_write_8
    415 
    416 /*
    417  *	void bus_space_write_multi_N(bus_space_tag_t tag,
    418  *	    bus_space_handle_t bsh, bus_size_t offset,
    419  *	    const uintN_t *addr, size_t count);
    420  *
    421  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
    422  * provided to bus space described by tag/handle/offset.
    423  */
    424 
    425 #define	bus_space_write_multi_1(t, h, o, ptr, cnt)			\
    426 do {									\
    427 	if ((t) == IA64_BUS_SPACE_IO) {					\
    428 		outsb((h) + (o), (ptr), (cnt));				\
    429 	} else {							\
    430 		int __i;						\
    431 		volatile uint8_t *__p = (uint8_t *)((h) + (o));		\
    432 		uint8_t *__src = (ptr);					\
    433 		for (__i = 0; __i < (cnt); __i++)			\
    434 			*__p = *__src++;				\
    435 	}								\
    436 } while (/* CONSTCOND */ 0)
    437 
    438 #define bus_space_write_multi_2(t, h, o, ptr, cnt)			\
    439 do {									\
    440 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint16_t, "buffer");		\
    441 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr");	\
    442 	if ((t) == IA64_BUS_SPACE_IO) {					\
    443 		outsw((h) + (o), (ptr), (cnt));				\
    444 	} else {							\
    445 		int __i;						\
    446 		volatile uint16_t *__p = (uint16_t *)((h) + (o));	\
    447 		uint16_t *__src = (ptr);				\
    448 		for (__i = 0; __i < (cnt); __i++)			\
    449 			*__p = *__src++;				\
    450 	}								\
    451 } while (/* CONSTCOND */ 0)
    452 
    453 #define bus_space_write_multi_4(t, h, o, ptr, cnt)			\
    454 do {									\
    455 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint32_t, "buffer");		\
    456 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr");	\
    457 	if ((t) == IA64_BUS_SPACE_IO) {					\
    458 		outsl((h) + (o), (ptr), (cnt));				\
    459 	} else {							\
    460 		int __i;						\
    461 		volatile uint32_t *__p = (uint32_t *)((h) + (o));	\
    462 		uint32_t *__src = (ptr);				\
    463 		for (__i = 0; __i < (cnt); __i++)			\
    464 			*__p = *__src++;				\
    465 	}								\
    466 } while (/* CONSTCOND */ 0)
    467 
    468 #define bus_space_write_multi_8(t, h, o, ptr, cnt)			\
    469 do {									\
    470 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint64_t, "buffer");		\
    471 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr");	\
    472 	if ((t) == IA64_BUS_SPACE_IO) {					\
    473 		printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__);\
    474 	} else {							\
    475 		int __i;						\
    476 		volatile uint64_t *__p = (uint64_t *)((h) + (o));	\
    477 		uint64_t *__src = (ptr);				\
    478 		for (__i = 0; __i < (cnt); __i++)			\
    479 			*__p = *__src++;				\
    480 	}								\
    481 } while (/* CONSTCOND */ 0)
    482 
    483 #define bus_space_write_multi_stream_1 bus_space_write_multi_1
    484 #define bus_space_write_multi_stream_2 bus_space_write_multi_2
    485 #define bus_space_write_multi_stream_4 bus_space_write_multi_4
    486 #define bus_space_write_multi_stream_8 bus_space_write_multi_8
    487 
    488 
    489 /*
    490  *	void bus_space_write_region_N(bus_space_tag_t tag,
    491  *	    bus_space_handle_t bsh, bus_size_t offset,
    492  *	    const uintN_t *addr, size_t count);
    493  *
    494  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
    495  * to bus space described by tag/handle starting at `offset'.
    496  */
    497 
    498 #define	bus_space_write_region_1(t, h, o, ptr, cnt)			\
    499 do {									\
    500 	if ((t) == IA64_BUS_SPACE_IO) {					\
    501 		int __i;						\
    502 		volatile bus_addr_t __port = (h) + (o);			\
    503 		uint8_t *__src = (ptr);					\
    504 		for (__i = 0; __i < (cnt); __i++) {			\
    505 			outb(__port, *__src);				\
    506 			__port++;					\
    507 			__src++;					\
    508 		}							\
    509 	} else {							\
    510 		int __i;						\
    511 		volatile uint8_t *__p = (uint8_t *)((h) + (o));		\
    512 		uint8_t *__src = (ptr);					\
    513 		for (__i = 0; __i < (cnt); __i++)			\
    514 			*__p++ = *__src++;				\
    515 	}								\
    516 } while (/* CONSTCOND */ 0)
    517 
    518 #define	bus_space_write_region_2(t, h, o, ptr, cnt)			\
    519 do {									\
    520 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint16_t, "buffer");		\
    521 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr");	\
    522 	if ((t) == IA64_BUS_SPACE_IO) {					\
    523 		int __i;						\
    524 		volatile bus_addr_t __port = (h) + (o);			\
    525 		uint16_t *__src = (ptr);				\
    526 		for (__i = 0; __i < (cnt); __i++) {			\
    527 			outw(__port, *__src);				\
    528 			__port += 2;					\
    529 			__src++;					\
    530 		}							\
    531 	} else {							\
    532 		int __i;						\
    533 		volatile uint16_t *__p = (uint16_t *)((h) + (o));	\
    534 		uint16_t *__src = (ptr);				\
    535 		for (__i = 0; __i < (cnt); __i++)			\
    536 			*__p++ = *__src++;				\
    537 	}								\
    538 } while (/* CONSTCOND */ 0)
    539 
    540 #define	bus_space_write_region_4(t, h, o, ptr, cnt)			\
    541 do {									\
    542 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint32_t, "buffer");		\
    543 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr");	\
    544 	if ((t) == IA64_BUS_SPACE_IO) {					\
    545 		int __i;						\
    546 		volatile bus_addr_t __port = (h) + (o);			\
    547 		uint32_t *__src = (ptr);				\
    548 		for (__i = 0; __i < (cnt); __i++) {			\
    549 			outl(__port, *__src);				\
    550 			__port += 4;					\
    551 			__src++;					\
    552 		}							\
    553 	} else {							\
    554 		int __i;						\
    555 		volatile uint32_t *__p = (uint32_t *)(h) + (o);		\
    556 		uint32_t *__src = (ptr);				\
    557 		for (__i = 0; __i < (cnt); __i++)			\
    558 			*__p++ = *__src++;				\
    559 	}								\
    560 } while (/* CONSTCOND */ 0)
    561 
    562 #define	bus_space_write_region_8(t, h, o, ptr, cnt)			\
    563 do {									\
    564 	__BUS_SPACE_ADDRESS_SANITY((ptr), uint64_t, "buffer");		\
    565 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr");	\
    566 	if ((t) == IA64_BUS_SPACE_IO) {					\
    567 		printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__);\
    568 	} else {							\
    569 		int __i;						\
    570 		volatile uint64_t *__p = (uint64_t *)((h) + (o));	\
    571 		uint64_t *__src = (ptr);				\
    572 		for (__i = 0; __i < (cnt); __i++)			\
    573 			*__p++ = *__src++;				\
    574 	}								\
    575 } while (/* CONSTCOND */ 0)
    576 
    577 #define bus_space_write_region_stream_1 bus_space_write_region_1
    578 #define bus_space_write_region_stream_2 bus_space_write_region_2
    579 #define bus_space_write_region_stream_4 bus_space_write_region_4
    580 #define bus_space_write_region_stream_8 bus_space_write_region_8
    581 
    582 
    583 /*
    584  *	void bus_space_set_multi_N(bus_space_tag_t tag,
    585  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
    586  *	    size_t count);
    587  *
    588  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
    589  * by tag/handle/offset `count' times.
    590  */
    591 
    592 static __inline void ia64_bus_space_set_multi_1(bus_space_tag_t,
    593 	bus_space_handle_t, bus_size_t, uint8_t, size_t);
    594 static __inline void ia64_bus_space_set_multi_2(bus_space_tag_t,
    595 	bus_space_handle_t, bus_size_t, uint16_t, size_t);
    596 static __inline void ia64_bus_space_set_multi_4(bus_space_tag_t,
    597 	bus_space_handle_t, bus_size_t, uint32_t, size_t);
    598 static __inline void ia64_bus_space_set_multi_8(bus_space_tag_t,
    599 	bus_space_handle_t, bus_size_t, uint64_t, size_t);
    600 
    601 #define	bus_space_set_multi_1(t, h, o, v, c)				\
    602 	ia64_bus_space_set_multi_1((t), (h), (o), (v), (c))
    603 
    604 #define	bus_space_set_multi_2(t, h, o, v, c)				\
    605 do {									\
    606 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr");	\
    607 	ia64_bus_space_set_multi_2((t), (h), (o), (v), (c));		\
    608 } while (/* CONSTCOND */ 0)
    609 
    610 #define	bus_space_set_multi_4(t, h, o, v, c)				\
    611 do {									\
    612 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr");	\
    613 	ia64_bus_space_set_multi_4((t), (h), (o), (v), (c));		\
    614 } while (/* CONSTCOND */ 0)
    615 
    616 #define	bus_space_set_multi_8(t, h, o, v, c)				\
    617 do {									\
    618 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr");	\
    619 	ia64_bus_space_set_multi_8((t), (h), (o), (v), (c));		\
    620 } while (/* CONSTCOND */ 0)
    621 
    622 static __inline void
    623 ia64_bus_space_set_multi_1(bus_space_tag_t t, bus_space_handle_t h,
    624     bus_size_t o, uint8_t v, size_t c)
    625 {
    626 	bus_addr_t addr = h + o;
    627 
    628 	if (t == IA64_BUS_SPACE_IO)
    629 		while (c--)
    630 			outb(addr, v);
    631 	else
    632 		while (c--)
    633 			*(volatile uint8_t *)(addr) = v;
    634 }
    635 
    636 static __inline void
    637 ia64_bus_space_set_multi_2(bus_space_tag_t t, bus_space_handle_t h,
    638     bus_size_t o, uint16_t v, size_t c)
    639 {
    640 	bus_addr_t addr = h + o;
    641 
    642 	if (t == IA64_BUS_SPACE_IO)
    643 		while (c--)
    644 			outw(addr, v);
    645 	else
    646 		while (c--)
    647 			*(volatile uint16_t *)(addr) = v;
    648 }
    649 
    650 static __inline void
    651 ia64_bus_space_set_multi_4(bus_space_tag_t t, bus_space_handle_t h,
    652     bus_size_t o, uint32_t v, size_t c)
    653 {
    654 	bus_addr_t addr = h + o;
    655 
    656 	if (t == IA64_BUS_SPACE_IO)
    657 		while (c--)
    658 			outl(addr, v);
    659 	else
    660 		while (c--)
    661 			*(volatile uint32_t *)(addr) = v;
    662 }
    663 
    664 static __inline void
    665 ia64_bus_space_set_multi_8(bus_space_tag_t t, bus_space_handle_t h,
    666     bus_size_t o, uint64_t v, size_t c)
    667 {
    668 	bus_addr_t addr = h + o;
    669 
    670 	if (t == IA64_BUS_SPACE_IO)
    671 		printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__);
    672 	else
    673 		while (c--)
    674 			*(volatile uint64_t *)(addr) = v;
    675 }
    676 
    677 
    678 /*
    679  *	void bus_space_set_region_N(bus_space_tag_t tag,
    680  *	    bus_space_handle_t bsh, bus_size_t offset, uintN_t val,
    681  *	    size_t count);
    682  *
    683  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
    684  * by tag/handle starting at `offset'.
    685  */
    686 
    687 static __inline void ia64_bus_space_set_region_1(bus_space_tag_t,
    688 	bus_space_handle_t, bus_size_t, uint8_t, size_t);
    689 static __inline void ia64_bus_space_set_region_2(bus_space_tag_t,
    690 	bus_space_handle_t, bus_size_t, uint16_t, size_t);
    691 static __inline void ia64_bus_space_set_region_4(bus_space_tag_t,
    692 	bus_space_handle_t, bus_size_t, uint32_t, size_t);
    693 
    694 #define	bus_space_set_region_1(t, h, o, v, c)				\
    695 	ia64_bus_space_set_region_1((t), (h), (o), (v), (c))
    696 
    697 #define	bus_space_set_region_2(t, h, o, v, c)				\
    698 do {									\
    699 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint16_t, "bus addr");	\
    700 	ia64_bus_space_set_region_2((t), (h), (o), (v), (c));		\
    701 } while (/* CONSTCOND */ 0)
    702 
    703 #define	bus_space_set_region_4(t, h, o, v, c)				\
    704 do {									\
    705 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint32_t, "bus addr");	\
    706 	ia64_bus_space_set_region_4((t), (h), (o), (v), (c));		\
    707 } while (/* CONSTCOND */ 0)
    708 
    709 #define	bus_space_set_region_8(t, h, o, v, c)				\
    710 do {									\
    711 	__BUS_SPACE_ADDRESS_SANITY((h) + (o), uint64_t, "bus addr");	\
    712 	ia64_bus_space_set_region_8((t), (h), (o), (v), (c));		\
    713 } while (/* CONSTCOND */ 0)
    714 
    715 static __inline void
    716 ia64_bus_space_set_region_1(bus_space_tag_t t, bus_space_handle_t h,
    717     bus_size_t o, uint8_t v, size_t c)
    718 {
    719 	bus_addr_t addr = h + o;
    720 
    721 	if (t == IA64_BUS_SPACE_IO)
    722 		for (; c != 0; c--, addr++)
    723 			outb(addr, v);
    724 	else
    725 		for (; c != 0; c--, addr++)
    726 			*(volatile uint8_t *)(addr) = v;
    727 }
    728 
    729 static __inline void
    730 ia64_bus_space_set_region_2(bus_space_tag_t t, bus_space_handle_t h,
    731     bus_size_t o, uint16_t v, size_t c)
    732 {
    733 	bus_addr_t addr = h + o;
    734 
    735 	if (t == IA64_BUS_SPACE_IO)
    736 		for (; c != 0; c--, addr += 2)
    737 			outw(addr, v);
    738 	else
    739 		for (; c != 0; c--, addr += 2)
    740 			*(volatile uint16_t *)(addr) = v;
    741 }
    742 
    743 static __inline void
    744 ia64_bus_space_set_region_4(bus_space_tag_t t, bus_space_handle_t h,
    745     bus_size_t o, uint32_t v, size_t c)
    746 {
    747 	bus_addr_t addr = h + o;
    748 
    749 	if (t == IA64_BUS_SPACE_IO)
    750 		for (; c != 0; c--, addr += 4)
    751 			outl(addr, v);
    752 	else
    753 		for (; c != 0; c--, addr += 4)
    754 			*(volatile uint32_t *)(addr) = v;
    755 }
    756 
    757 static __inline void
    758 ia64_bus_space_set_region_8(bus_space_tag_t t, bus_space_handle_t h,
    759     bus_size_t o, uint64_t v, size_t c)
    760 {
    761 	bus_addr_t addr = h + o;
    762 
    763 	if (t == IA64_BUS_SPACE_IO)
    764 		printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__);
    765 	else
    766 		for (; c != 0; c--, addr += 8)
    767 			*(volatile uint32_t *)(addr) = v;
    768 }
    769 
    770 
    771 /*
    772  *	void bus_space_copy_region_N(bus_space_tag_t tag,
    773  *	    bus_space_handle_t bsh1, bus_size_t off1,
    774  *	    bus_space_handle_t bsh2, bus_size_t off2,
    775  *	    size_t count);
    776  *
    777  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
    778  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
    779  */
    780 
    781 static __inline void ia64_bus_space_copy_region_1(bus_space_tag_t,
    782 	bus_space_handle_t, bus_size_t, bus_space_handle_t,
    783 	bus_size_t, size_t);
    784 static __inline void ia64_bus_space_copy_region_2(bus_space_tag_t,
    785 	bus_space_handle_t, bus_size_t, bus_space_handle_t,
    786 	bus_size_t, size_t);
    787 static __inline void ia64_bus_space_copy_region_4(bus_space_tag_t,
    788 	bus_space_handle_t, bus_size_t, bus_space_handle_t,
    789 	bus_size_t, size_t);
    790 
    791 #define	bus_space_copy_region_1(t, h1, o1, h2, o2, c)			\
    792 	ia64_bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
    793 
    794 #define	bus_space_copy_region_2(t, h1, o1, h2, o2, c)			\
    795 do {									\
    796 	__BUS_SPACE_ADDRESS_SANITY((h1) + (o1), uint16_t, "bus addr 1"); \
    797 	__BUS_SPACE_ADDRESS_SANITY((h2) + (o2), uint16_t, "bus addr 2"); \
    798 	ia64_bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c));	\
    799 } while (/* CONSTCOND */ 0)
    800 
    801 #define	bus_space_copy_region_4(t, h1, o1, h2, o2, c)			\
    802 do {									\
    803 	__BUS_SPACE_ADDRESS_SANITY((h1) + (o1), uint32_t, "bus addr 1"); \
    804 	__BUS_SPACE_ADDRESS_SANITY((h2) + (o2), uint32_t, "bus addr 2"); \
    805 	ia64_bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c));	\
    806 } while (/* CONSTCOND */ 0)
    807 
    808 #define	bus_space_copy_region_8(t, h1, o1, h2, o2, c)			\
    809 do {									\
    810 	__BUS_SPACE_ADDRESS_SANITY((h1) + (o1), uint64_t, "bus addr 1"); \
    811 	__BUS_SPACE_ADDRESS_SANITY((h2) + (o2), uint64_t, "bus addr 2"); \
    812 	ia64_bus_space_copy_region_8((t), (h1), (o1), (h2), (o2), (c));	\
    813 } while (/* CONSTCOND */ 0)
    814 
    815 static __inline void
    816 ia64_bus_space_copy_region_1(bus_space_tag_t t,
    817     bus_space_handle_t h1, bus_size_t o1,
    818     bus_space_handle_t h2, bus_size_t o2, size_t c)
    819 {
    820 	bus_addr_t addr1 = h1 + o1;
    821 	bus_addr_t addr2 = h2 + o2;
    822 
    823 	if (t == IA64_BUS_SPACE_IO) {
    824 		if (addr1 >= addr2) {
    825 			/* src after dest: copy forward */
    826 			for (; c != 0; c--, addr1++, addr2++)
    827 				outb(addr2, inb(addr1));
    828 		} else {
    829 			/* dest after src: copy backwards */
    830 			for (addr1 += (c - 1), addr2 += (c - 1);
    831 			    c != 0; c--, addr1--, addr2--)
    832 				outb(addr2, inb(addr1));
    833 		}
    834 	} else {
    835 		if (addr1 >= addr2) {
    836 			/* src after dest: copy forward */
    837 			for (; c != 0; c--, addr1++, addr2++)
    838 				*(volatile uint8_t *)(addr2) =
    839 				    *(volatile uint8_t *)(addr1);
    840 		} else {
    841 			/* dest after src: copy backwards */
    842 			for (addr1 += (c - 1), addr2 += (c - 1);
    843 			    c != 0; c--, addr1--, addr2--)
    844 				*(volatile uint8_t *)(addr2) =
    845 				    *(volatile uint8_t *)(addr1);
    846 		}
    847 	}
    848 }
    849 
    850 static __inline void
    851 ia64_bus_space_copy_region_2(bus_space_tag_t t,
    852     bus_space_handle_t h1, bus_size_t o1,
    853     bus_space_handle_t h2, bus_size_t o2, size_t c)
    854 {
    855 	bus_addr_t addr1 = h1 + o1;
    856 	bus_addr_t addr2 = h2 + o2;
    857 
    858 	if (t == IA64_BUS_SPACE_IO) {
    859 		if (addr1 >= addr2) {
    860 			/* src after dest: copy forward */
    861 			for (; c != 0; c--, addr1 += 2, addr2 += 2)
    862 				outw(addr2, inw(addr1));
    863 		} else {
    864 			/* dest after src: copy backwards */
    865 			for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
    866 			    c != 0; c--, addr1 -= 2, addr2 -= 2)
    867 				outw(addr2, inw(addr1));
    868 		}
    869 	} else {
    870 		if (addr1 >= addr2) {
    871 			/* src after dest: copy forward */
    872 			for (; c != 0; c--, addr1 += 2, addr2 += 2)
    873 				*(volatile uint16_t *)(addr2) =
    874 				    *(volatile uint16_t *)(addr1);
    875 		} else {
    876 			/* dest after src: copy backwards */
    877 			for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
    878 			    c != 0; c--, addr1 -= 2, addr2 -= 2)
    879 				*(volatile uint16_t *)(addr2) =
    880 				    *(volatile uint16_t *)(addr1);
    881 		}
    882 	}
    883 }
    884 
    885 static __inline void
    886 ia64_bus_space_copy_region_4(bus_space_tag_t t,
    887     bus_space_handle_t h1, bus_size_t o1,
    888     bus_space_handle_t h2, bus_size_t o2, size_t c)
    889 {
    890 	bus_addr_t addr1 = h1 + o1;
    891 	bus_addr_t addr2 = h2 + o2;
    892 
    893 	if (t == IA64_BUS_SPACE_IO) {
    894 		if (addr1 >= addr2) {
    895 			/* src after dest: copy forward */
    896 			for (; c != 0; c--, addr1 += 4, addr2 += 4)
    897 				outl(addr2, inl(addr1));
    898 		} else {
    899 			/* dest after src: copy backwards */
    900 			for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
    901 			    c != 0; c--, addr1 -= 4, addr2 -= 4)
    902 				outl(addr2, inl(addr1));
    903 		}
    904 	} else {
    905 		if (addr1 >= addr2) {
    906 			/* src after dest: copy forward */
    907 			for (; c != 0; c--, addr1 += 4, addr2 += 4)
    908 				*(volatile uint32_t *)(addr2) =
    909 				    *(volatile uint32_t *)(addr1);
    910 		} else {
    911 			/* dest after src: copy backwards */
    912 			for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
    913 			    c != 0; c--, addr1 -= 4, addr2 -= 4)
    914 				*(volatile uint32_t *)(addr2) =
    915 				    *(volatile uint32_t *)(addr1);
    916 		}
    917 	}
    918 }
    919 
    920 static __inline void
    921 ia64_bus_space_copy_region_8(bus_space_tag_t t,
    922     bus_space_handle_t h1, bus_size_t o1,
    923     bus_space_handle_t h2, bus_size_t o2, size_t c)
    924 {
    925 	bus_addr_t addr1 = h1 + o1;
    926 	bus_addr_t addr2 = h2 + o2;
    927 
    928 	if (t == IA64_BUS_SPACE_IO) {
    929 		printf("%s: can't write 8bytes to I/O space\n", __FUNCTION__);
    930 	} else {
    931 		if (addr1 >= addr2) {
    932 			/* src after dest: copy forward */
    933 			for (; c != 0; c--, addr1 += 8, addr2 += 8)
    934 				*(volatile uint64_t *)(addr2) =
    935 				    *(volatile uint64_t *)(addr1);
    936 		} else {
    937 			/* dest after src: copy backwards */
    938 			for (addr1 += 8 * (c - 1), addr2 += 8 * (c - 1);
    939 			    c != 0; c--, addr1 -= 8, addr2 -= 8)
    940 				*(volatile uint64_t *)(addr2) =
    941 				    *(volatile uint64_t *)(addr1);
    942 		}
    943 	}
    944 }
    945 
    946 
    947 /*
    948  * Bus read/write barrier methods.
    949  *
    950  *	void bus_space_barrier(bus_space_tag_t tag,
    951  *	    bus_space_handle_t bsh, bus_size_t offset,
    952  *	    bus_size_t len, int flags);
    953  *
    954  * Note: the x86 does not currently require barriers, but we must
    955  * provide the flags to MI code.
    956  */
    957 #define	bus_space_barrier(t, h, o, l, f)	\
    958 	ia64_bus_space_barrier((t), (h), (o), (l), (f))
    959 
    960 
    961 #define	BUS_SPACE_BARRIER_READ	0x01
    962 #define	BUS_SPACE_BARRIER_WRITE	0x02
    963 
    964 /* XXX to be investigated: are these used? */
    965 #define	BUS_SPACE_BARRIER_READ_BEFORE_READ	0x04
    966 #define	BUS_SPACE_BARRIER_READ_BEFORE_WRITE	0x08
    967 #define	BUS_SPACE_BARRIER_WRITE_BEFORE_READ	0x10
    968 #define	BUS_SPACE_BARRIER_WRITE_BEFORE_WRITE	0x20
    969 #define	BUS_SPACE_BARRIER_SYNC			0x40
    970 
    971 static __inline void
    972 ia64_bus_space_barrier(bus_space_tag_t t, bus_space_handle_t handle,
    973     bus_size_t offset, bus_size_t length, int flags)
    974 {
    975 	if (t == IA64_BUS_SPACE_IO)
    976 		return;
    977 
    978 	switch (flags) {
    979 	case BUS_SPACE_BARRIER_READ:
    980 		__asm volatile("mf" ::: "memory");
    981 		break;
    982 	case BUS_SPACE_BARRIER_WRITE:
    983 		__asm volatile("mf" ::: "memory");
    984 		break;
    985 	case BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE:
    986 		__asm volatile("mf" ::: "memory");
    987 		break;
    988 	default:
    989 		printf("%s: Unknown barrier %d\n", __FUNCTION__, flags);
    990 		break;
    991 	}
    992 }
    993 
    994 
    995 /*
    996  * Flags used in various bus DMA methods.
    997  */
    998 #define	BUS_DMA_WAITOK		0x000	/* safe to sleep (pseudo-flag) */
    999 #define	BUS_DMA_NOWAIT		0x001	/* not safe to sleep */
   1000 #define	BUS_DMA_ALLOCNOW	0x002	/* perform resource allocation now */
   1001 #define	BUS_DMA_COHERENT	0x004	/* hint: map memory DMA coherent */
   1002 #define	BUS_DMA_STREAMING	0x008	/* hint: sequential, unidirectional */
   1003 #define	BUS_DMA_BUS1		0x010	/* placeholders for bus functions... */
   1004 #define	BUS_DMA_BUS2		0x020
   1005 #define	BUS_DMA_BUS3		0x040
   1006 #define	BUS_DMA_BUS4		0x080
   1007 #define	BUS_DMA_READ		0x100	/* mapping is device -> memory only */
   1008 #define	BUS_DMA_WRITE		0x200	/* mapping is memory -> device only */
   1009 #define	BUS_DMA_NOCACHE		0x400	/* hint: map non-cached memory */
   1010 
   1011 /* Forwards needed by prototypes below. */
   1012 struct mbuf;
   1013 struct uio;
   1014 
   1015 /*
   1016  * Operations performed by bus_dmamap_sync().
   1017  */
   1018 #define	BUS_DMASYNC_PREREAD	0x01	/* pre-read synchronization */
   1019 #define	BUS_DMASYNC_POSTREAD	0x02	/* post-read synchronization */
   1020 #define	BUS_DMASYNC_PREWRITE	0x04	/* pre-write synchronization */
   1021 #define	BUS_DMASYNC_POSTWRITE	0x08	/* post-write synchronization */
   1022 
   1023 typedef struct ia64_bus_dma_tag		*bus_dma_tag_t;
   1024 typedef struct ia64_bus_dmamap		*bus_dmamap_t;
   1025 
   1026 #define BUS_DMA_TAG_VALID(t)    ((t) != (bus_dma_tag_t)0)
   1027 
   1028 /*
   1029  *	bus_dma_segment_t
   1030  *
   1031  *	Describes a single contiguous DMA transaction.  Values
   1032  *	are suitable for programming into DMA registers.
   1033  */
   1034 struct ia64_bus_dma_segment {
   1035 	bus_addr_t	ds_addr;	/* DMA address */
   1036 	bus_size_t	ds_len;		/* length of transfer */
   1037 };
   1038 typedef struct ia64_bus_dma_segment	bus_dma_segment_t;
   1039 
   1040 /*
   1041  *	bus_dma_tag_t
   1042  *
   1043  *	A machine-dependent opaque type describing the implementation of
   1044  *	DMA for a given bus.
   1045  */
   1046 
   1047 struct ia64_bus_dma_tag {
   1048 	/*
   1049 	 * The `bounce threshold' is checked while we are loading
   1050 	 * the DMA map.  If the physical address of the segment
   1051 	 * exceeds the threshold, an error will be returned.  The
   1052 	 * caller can then take whatever action is necessary to
   1053 	 * bounce the transfer.  If this value is 0, it will be
   1054 	 * ignored.
   1055 	 */
   1056 	bus_addr_t _bounce_thresh;
   1057 	bus_addr_t _bounce_alloc_lo;
   1058 	bus_addr_t _bounce_alloc_hi;
   1059 	int	(*_may_bounce)(bus_dma_tag_t, bus_dmamap_t, int, int *);
   1060 
   1061 	/*
   1062 	 * DMA mapping methods.
   1063 	 */
   1064 	int	(*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
   1065 		    bus_size_t, bus_size_t, int, bus_dmamap_t *);
   1066 	void	(*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
   1067 	int	(*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
   1068 		    bus_size_t, struct proc *, int);
   1069 	int	(*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
   1070 		    struct mbuf *, int);
   1071 	int	(*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
   1072 		    struct uio *, int);
   1073 	int	(*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
   1074 		    bus_dma_segment_t *, int, bus_size_t, int);
   1075 	void	(*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
   1076 	void	(*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
   1077 		    bus_addr_t, bus_size_t, int);
   1078 
   1079 	/*
   1080 	 * DMA memory utility functions.
   1081 	 */
   1082 	int	(*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
   1083 		    bus_size_t, bus_dma_segment_t *, int, int *, int);
   1084 	void	(*_dmamem_free)(bus_dma_tag_t, bus_dma_segment_t *, int);
   1085 	int	(*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
   1086 		    int, size_t, void **, int);
   1087 	void	(*_dmamem_unmap)(bus_dma_tag_t, void *, size_t);
   1088 	paddr_t	(*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
   1089 		    int, off_t, int, int);
   1090 };
   1091 
   1092 static __inline void bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t,
   1093     bus_addr_t, bus_size_t, int) __attribute__((__unused__));
   1094 
   1095 #define	bus_dmamap_create(t, s, n, m, b, f, p)			\
   1096 	(*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
   1097 #define	bus_dmamap_destroy(t, p)				\
   1098 	(*(t)->_dmamap_destroy)((t), (p))
   1099 #define	bus_dmamap_load(t, m, b, s, p, f)			\
   1100 	(*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
   1101 #define	bus_dmamap_load_mbuf(t, m, b, f)			\
   1102 	(*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
   1103 #define	bus_dmamap_load_uio(t, m, u, f)				\
   1104 	(*(t)->_dmamap_load_uio)((t), (m), (u), (f))
   1105 #define	bus_dmamap_load_raw(t, m, sg, n, s, f)			\
   1106 	(*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
   1107 #define	bus_dmamap_unload(t, p)					\
   1108 	(*(t)->_dmamap_unload)((t), (p))
   1109 static __inline void
   1110 bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t p, bus_addr_t o, bus_size_t l,
   1111     int ops)
   1112 {
   1113 	/* if (ops & BUS_DMASYNC_POSTREAD)
   1114 	   x86_lfence(); */
   1115 	if (t->_dmamap_sync)
   1116 		(*t->_dmamap_sync)(t, p, o, l, ops);
   1117 }
   1118 
   1119 #define	bus_dmamem_alloc(t, s, a, b, sg, n, r, f)		\
   1120 	(*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
   1121 #define	bus_dmamem_free(t, sg, n)				\
   1122 	(*(t)->_dmamem_free)((t), (sg), (n))
   1123 #define	bus_dmamem_map(t, sg, n, s, k, f)			\
   1124 	(*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
   1125 #define	bus_dmamem_unmap(t, k, s)				\
   1126 	(*(t)->_dmamem_unmap)((t), (k), (s))
   1127 #define	bus_dmamem_mmap(t, sg, n, o, p, f)			\
   1128 	(*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
   1129 
   1130 /*
   1131  *	bus_dmamap_t
   1132  *
   1133  *	Describes a DMA mapping.
   1134  */
   1135 struct ia64_bus_dmamap {
   1136 	/*
   1137 	 * PRIVATE MEMBERS: not for use by machine-independent code.
   1138 	 */
   1139 	bus_size_t	_dm_size;	/* largest DMA transfer mappable */
   1140 	int		_dm_segcnt;	/* number of segs this map can map */
   1141 	bus_size_t	_dm_maxmaxsegsz; /* fixed largest possible segment */
   1142 	bus_size_t	_dm_boundary;	/* don't cross this */
   1143 	bus_addr_t	_dm_bounce_thresh; /* bounce threshold; see tag */
   1144 	int		_dm_flags;	/* misc. flags */
   1145 
   1146 	void		*_dm_cookie;	/* cookie for bus-specific functions */
   1147 
   1148 	/*
   1149 	 * PUBLIC MEMBERS: these are used by machine-independent code.
   1150 	 */
   1151 	bus_size_t	dm_maxsegsz;	/* largest possible segment */
   1152 	bus_size_t	dm_mapsize;	/* size of the mapping */
   1153 	int		dm_nsegs;	/* # valid segments in mapping */
   1154 	bus_dma_segment_t dm_segs[1];	/* segments; variable length */
   1155 };
   1156 
   1157 #endif /* _IA64_BUS_H_ */
   1158