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