xref: /freebsd/sys/amd64/include/bus.h (revision 06db52b6)
1 /*-
2  * Copyright (c) KATO Takenori, 1999.
3  *
4  * All rights reserved.  Unpublished rights reserved under the copyright
5  * laws of Japan.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer as
13  *    the first lines of this file unmodified.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * $FreeBSD$
32  */
33 
34 /*	$NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $	*/
35 
36 /*-
37  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
38  * All rights reserved.
39  *
40  * This code is derived from software contributed to The NetBSD Foundation
41  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
42  * NASA Ames Research Center.
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 the NetBSD
55  *	Foundation, Inc. and its contributors.
56  * 4. Neither the name of The NetBSD Foundation nor the names of its
57  *    contributors may be used to endorse or promote products derived
58  *    from this software without specific prior written permission.
59  *
60  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
61  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
62  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
64  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
65  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
66  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
67  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
68  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
69  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
70  * POSSIBILITY OF SUCH DAMAGE.
71  */
72 
73 /*-
74  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
75  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
76  *
77  * Redistribution and use in source and binary forms, with or without
78  * modification, are permitted provided that the following conditions
79  * are met:
80  * 1. Redistributions of source code must retain the above copyright
81  *    notice, this list of conditions and the following disclaimer.
82  * 2. Redistributions in binary form must reproduce the above copyright
83  *    notice, this list of conditions and the following disclaimer in the
84  *    documentation and/or other materials provided with the distribution.
85  * 3. All advertising materials mentioning features or use of this software
86  *    must display the following acknowledgement:
87  *      This product includes software developed by Christopher G. Demetriou
88  *	for the NetBSD Project.
89  * 4. The name of the author may not be used to endorse or promote products
90  *    derived from this software without specific prior written permission
91  *
92  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
93  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
94  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
95  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
96  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
99  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
101  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
102  */
103 
104 #ifndef _AMD64_BUS_H_
105 #define _AMD64_BUS_H_
106 
107 #include <machine/_bus.h>
108 #include <machine/cpufunc.h>
109 
110 /*
111  * To remain compatible with NetBSD's interface, default to both memio and
112  * pio when neither of them is defined.
113  */
114 #if !defined(_AMD64_BUS_PIO_H_) && !defined(_AMD64_BUS_MEMIO_H_)
115 #define _AMD64_BUS_PIO_H_
116 #define _AMD64_BUS_MEMIO_H_
117 #endif
118 
119 /*
120  * Values for the amd64 bus space tag, not to be used directly by MI code.
121  */
122 #define	AMD64_BUS_SPACE_IO	0	/* space is i/o space */
123 #define AMD64_BUS_SPACE_MEM	1	/* space is mem space */
124 
125 /*
126  * Bus address and size types
127  */
128 #define BUS_SPACE_MAXSIZE_24BIT	0xFFFFFF
129 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
130 #define BUS_SPACE_MAXSIZE	0xFFFFFFFF
131 #define BUS_SPACE_MAXADDR_24BIT	0xFFFFFF
132 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
133 #define BUS_SPACE_MAXADDR	0xFFFFFFFFFFFFFFFFULL
134 
135 #define BUS_SPACE_UNRESTRICTED	(~0)
136 
137 /*
138  * Map a region of device bus space into CPU virtual address space.
139  */
140 
141 static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
142 				  bus_size_t size, int flags,
143 				  bus_space_handle_t *bshp);
144 
145 static __inline int
146 bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
147 	      bus_size_t size __unused, int flags __unused,
148 	      bus_space_handle_t *bshp)
149 {
150 
151 	*bshp = addr;
152 	return (0);
153 }
154 
155 /*
156  * Unmap a region of device bus space.
157  */
158 
159 static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
160 				     bus_size_t size);
161 
162 static __inline void
163 bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
164 		bus_size_t size __unused)
165 {
166 }
167 
168 /*
169  * Get a new handle for a subregion of an already-mapped area of bus space.
170  */
171 
172 static __inline int bus_space_subregion(bus_space_tag_t t,
173 					bus_space_handle_t bsh,
174 					bus_size_t offset, bus_size_t size,
175 					bus_space_handle_t *nbshp);
176 
177 static __inline int
178 bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
179 		    bus_size_t offset, bus_size_t size __unused,
180 		    bus_space_handle_t *nbshp)
181 {
182 
183 	*nbshp = bsh + offset;
184 	return (0);
185 }
186 
187 /*
188  * Allocate a region of memory that is accessible to devices in bus space.
189  */
190 
191 int	bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
192 			bus_addr_t rend, bus_size_t size, bus_size_t align,
193 			bus_size_t boundary, int flags, bus_addr_t *addrp,
194 			bus_space_handle_t *bshp);
195 
196 /*
197  * Free a region of bus space accessible memory.
198  */
199 
200 static __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
201 				    bus_size_t size);
202 
203 static __inline void
204 bus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
205 	       bus_size_t size __unused)
206 {
207 }
208 
209 
210 #if defined(_AMD64_BUS_PIO_H_) || defined(_AMD64_BUS_MEMIO_H_)
211 
212 /*
213  * Read a 1, 2, 4, or 8 byte quantity from bus space
214  * described by tag/handle/offset.
215  */
216 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
217 					  bus_space_handle_t handle,
218 					  bus_size_t offset);
219 
220 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
221 					   bus_space_handle_t handle,
222 					   bus_size_t offset);
223 
224 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
225 					   bus_space_handle_t handle,
226 					   bus_size_t offset);
227 
228 static __inline u_int8_t
229 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
230 		 bus_size_t offset)
231 {
232 #if defined (_AMD64_BUS_PIO_H_)
233 #if defined (_AMD64_BUS_MEMIO_H_)
234 	if (tag == AMD64_BUS_SPACE_IO)
235 #endif
236 		return (inb(handle + offset));
237 #endif
238 #if defined (_AMD64_BUS_MEMIO_H_)
239 	return (*(volatile u_int8_t *)(handle + offset));
240 #endif
241 }
242 
243 static __inline u_int16_t
244 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
245 		 bus_size_t offset)
246 {
247 #if defined(_AMD64_BUS_PIO_H_)
248 #if defined(_AMD64_BUS_MEMIO_H_)
249 	if (tag == AMD64_BUS_SPACE_IO)
250 #endif
251 		return (inw(handle + offset));
252 #endif
253 #if defined(_AMD64_BUS_MEMIO_H_)
254 	return (*(volatile u_int16_t *)(handle + offset));
255 #endif
256 }
257 
258 static __inline u_int32_t
259 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
260 		 bus_size_t offset)
261 {
262 #if defined(_AMD64_BUS_PIO_H_)
263 #if defined(_AMD64_BUS_MEMIO_H_)
264 	if (tag == AMD64_BUS_SPACE_IO)
265 #endif
266 		return (inl(handle + offset));
267 #endif
268 #if defined(_AMD64_BUS_MEMIO_H_)
269 	return (*(volatile u_int32_t *)(handle + offset));
270 #endif
271 }
272 
273 #if 0	/* Cause a link error for bus_space_read_8 */
274 #define	bus_space_read_8(t, h, o)	!!! bus_space_read_8 unimplemented !!!
275 #endif
276 
277 /*
278  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
279  * described by tag/handle/offset and copy into buffer provided.
280  */
281 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
282 					    bus_space_handle_t bsh,
283 					    bus_size_t offset, u_int8_t *addr,
284 					    size_t count);
285 
286 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
287 					    bus_space_handle_t bsh,
288 					    bus_size_t offset, u_int16_t *addr,
289 					    size_t count);
290 
291 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
292 					    bus_space_handle_t bsh,
293 					    bus_size_t offset, u_int32_t *addr,
294 					    size_t count);
295 
296 static __inline void
297 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
298 		       bus_size_t offset, u_int8_t *addr, size_t count)
299 {
300 #if defined(_AMD64_BUS_PIO_H_)
301 #if defined(_AMD64_BUS_MEMIO_H_)
302 	if (tag == AMD64_BUS_SPACE_IO)
303 #endif
304 		insb(bsh + offset, addr, count);
305 #endif
306 #if defined(_AMD64_BUS_MEMIO_H_)
307 #if defined(_AMD64_BUS_PIO_H_)
308 	else
309 #endif
310 	{
311 #ifdef __GNUCLIKE_ASM
312 		__asm __volatile("				\n\
313 			cld					\n\
314 		1:	movb (%2),%%al				\n\
315 			stosb					\n\
316 			loop 1b"				:
317 		    "=D" (addr), "=c" (count)			:
318 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
319 		    "%eax", "memory");
320 #endif
321 	}
322 #endif
323 }
324 
325 static __inline void
326 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
327 		       bus_size_t offset, u_int16_t *addr, size_t count)
328 {
329 #if defined(_AMD64_BUS_PIO_H_)
330 #if defined(_AMD64_BUS_MEMIO_H_)
331 	if (tag == AMD64_BUS_SPACE_IO)
332 #endif
333 		insw(bsh + offset, addr, count);
334 #endif
335 #if defined(_AMD64_BUS_MEMIO_H_)
336 #if defined(_AMD64_BUS_PIO_H_)
337 	else
338 #endif
339 	{
340 #ifdef __GNUCLIKE_ASM
341 		__asm __volatile("				\n\
342 			cld					\n\
343 		1:	movw (%2),%%ax				\n\
344 			stosw					\n\
345 			loop 1b"				:
346 		    "=D" (addr), "=c" (count)			:
347 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
348 		    "%eax", "memory");
349 #endif
350 	}
351 #endif
352 }
353 
354 static __inline void
355 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
356 		       bus_size_t offset, u_int32_t *addr, size_t count)
357 {
358 #if defined(_AMD64_BUS_PIO_H_)
359 #if defined(_AMD64_BUS_MEMIO_H_)
360 	if (tag == AMD64_BUS_SPACE_IO)
361 #endif
362 		insl(bsh + offset, addr, count);
363 #endif
364 #if defined(_AMD64_BUS_MEMIO_H_)
365 #if defined(_AMD64_BUS_PIO_H_)
366 	else
367 #endif
368 	{
369 #ifdef __GNUCLIKE_ASM
370 		__asm __volatile("				\n\
371 			cld					\n\
372 		1:	movl (%2),%%eax				\n\
373 			stosl					\n\
374 			loop 1b"				:
375 		    "=D" (addr), "=c" (count)			:
376 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
377 		    "%eax", "memory");
378 #endif
379 	}
380 #endif
381 }
382 
383 #if 0	/* Cause a link error for bus_space_read_multi_8 */
384 #define	bus_space_read_multi_8	!!! bus_space_read_multi_8 unimplemented !!!
385 #endif
386 
387 /*
388  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
389  * described by tag/handle and starting at `offset' and copy into
390  * buffer provided.
391  */
392 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
393 					     bus_space_handle_t bsh,
394 					     bus_size_t offset, u_int8_t *addr,
395 					     size_t count);
396 
397 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
398 					     bus_space_handle_t bsh,
399 					     bus_size_t offset, u_int16_t *addr,
400 					     size_t count);
401 
402 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
403 					     bus_space_handle_t bsh,
404 					     bus_size_t offset, u_int32_t *addr,
405 					     size_t count);
406 
407 
408 static __inline void
409 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
410 			bus_size_t offset, u_int8_t *addr, size_t count)
411 {
412 #if defined(_AMD64_BUS_PIO_H_)
413 #if defined(_AMD64_BUS_MEMIO_H_)
414 	if (tag == AMD64_BUS_SPACE_IO)
415 #endif
416 	{
417 		int _port_ = bsh + offset;
418 #ifdef __GNUCLIKE_ASM
419 		__asm __volatile("				\n\
420 			cld					\n\
421 		1:	inb %w2,%%al				\n\
422 			stosb					\n\
423 			incl %2					\n\
424 			loop 1b"				:
425 		    "=D" (addr), "=c" (count), "=d" (_port_)	:
426 		    "0" (addr), "1" (count), "2" (_port_)	:
427 		    "%eax", "memory", "cc");
428 #endif
429 	}
430 #endif
431 #if defined(_AMD64_BUS_MEMIO_H_)
432 #if defined(_AMD64_BUS_PIO_H_)
433 	else
434 #endif
435 	{
436 		bus_space_handle_t _port_ = bsh + offset;
437 #ifdef __GNUCLIKE_ASM
438 		__asm __volatile("				\n\
439 			cld					\n\
440 			repne					\n\
441 			movsb"					:
442 		    "=D" (addr), "=c" (count), "=S" (_port_)	:
443 		    "0" (addr), "1" (count), "2" (_port_)	:
444 		    "memory", "cc");
445 #endif
446 	}
447 #endif
448 }
449 
450 static __inline void
451 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
452 			bus_size_t offset, u_int16_t *addr, size_t count)
453 {
454 #if defined(_AMD64_BUS_PIO_H_)
455 #if defined(_AMD64_BUS_MEMIO_H_)
456 	if (tag == AMD64_BUS_SPACE_IO)
457 #endif
458 	{
459 		int _port_ = bsh + offset;
460 #ifdef __GNUCLIKE_ASM
461 		__asm __volatile("				\n\
462 			cld					\n\
463 		1:	inw %w2,%%ax				\n\
464 			stosw					\n\
465 			addl $2,%2				\n\
466 			loop 1b"				:
467 		    "=D" (addr), "=c" (count), "=d" (_port_)	:
468 		    "0" (addr), "1" (count), "2" (_port_)	:
469 		    "%eax", "memory", "cc");
470 #endif
471 	}
472 #endif
473 #if defined(_AMD64_BUS_MEMIO_H_)
474 #if defined(_AMD64_BUS_PIO_H_)
475 	else
476 #endif
477 	{
478 		bus_space_handle_t _port_ = bsh + offset;
479 #ifdef __GNUCLIKE_ASM
480 		__asm __volatile("				\n\
481 			cld					\n\
482 			repne					\n\
483 			movsw"					:
484 		    "=D" (addr), "=c" (count), "=S" (_port_)	:
485 		    "0" (addr), "1" (count), "2" (_port_)	:
486 		    "memory", "cc");
487 #endif
488 	}
489 #endif
490 }
491 
492 static __inline void
493 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
494 			bus_size_t offset, u_int32_t *addr, size_t count)
495 {
496 #if defined(_AMD64_BUS_PIO_H_)
497 #if defined(_AMD64_BUS_MEMIO_H_)
498 	if (tag == AMD64_BUS_SPACE_IO)
499 #endif
500 	{
501 		int _port_ = bsh + offset;
502 #ifdef __GNUCLIKE_ASM
503 		__asm __volatile("				\n\
504 			cld					\n\
505 		1:	inl %w2,%%eax				\n\
506 			stosl					\n\
507 			addl $4,%2				\n\
508 			loop 1b"				:
509 		    "=D" (addr), "=c" (count), "=d" (_port_)	:
510 		    "0" (addr), "1" (count), "2" (_port_)	:
511 		    "%eax", "memory", "cc");
512 #endif
513 	}
514 #endif
515 #if defined(_AMD64_BUS_MEMIO_H_)
516 #if defined(_AMD64_BUS_PIO_H_)
517 	else
518 #endif
519 	{
520 		bus_space_handle_t _port_ = bsh + offset;
521 #ifdef __GNUCLIKE_ASM
522 		__asm __volatile("				\n\
523 			cld					\n\
524 			repne					\n\
525 			movsl"					:
526 		    "=D" (addr), "=c" (count), "=S" (_port_)	:
527 		    "0" (addr), "1" (count), "2" (_port_)	:
528 		    "memory", "cc");
529 #endif
530 	}
531 #endif
532 }
533 
534 #if 0	/* Cause a link error for bus_space_read_region_8 */
535 #define	bus_space_read_region_8	!!! bus_space_read_region_8 unimplemented !!!
536 #endif
537 
538 /*
539  * Write the 1, 2, 4, or 8 byte value `value' to bus space
540  * described by tag/handle/offset.
541  */
542 
543 static __inline void bus_space_write_1(bus_space_tag_t tag,
544 				       bus_space_handle_t bsh,
545 				       bus_size_t offset, u_int8_t value);
546 
547 static __inline void bus_space_write_2(bus_space_tag_t tag,
548 				       bus_space_handle_t bsh,
549 				       bus_size_t offset, u_int16_t value);
550 
551 static __inline void bus_space_write_4(bus_space_tag_t tag,
552 				       bus_space_handle_t bsh,
553 				       bus_size_t offset, u_int32_t value);
554 
555 static __inline void
556 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
557 		       bus_size_t offset, u_int8_t value)
558 {
559 #if defined(_AMD64_BUS_PIO_H_)
560 #if defined(_AMD64_BUS_MEMIO_H_)
561 	if (tag == AMD64_BUS_SPACE_IO)
562 #endif
563 		outb(bsh + offset, value);
564 #endif
565 #if defined(_AMD64_BUS_MEMIO_H_)
566 #if defined(_AMD64_BUS_PIO_H_)
567 	else
568 #endif
569 		*(volatile u_int8_t *)(bsh + offset) = value;
570 #endif
571 }
572 
573 static __inline void
574 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
575 		       bus_size_t offset, u_int16_t value)
576 {
577 #if defined(_AMD64_BUS_PIO_H_)
578 #if defined(_AMD64_BUS_MEMIO_H_)
579 	if (tag == AMD64_BUS_SPACE_IO)
580 #endif
581 		outw(bsh + offset, value);
582 #endif
583 #if defined(_AMD64_BUS_MEMIO_H_)
584 #if defined(_AMD64_BUS_PIO_H_)
585 	else
586 #endif
587 		*(volatile u_int16_t *)(bsh + offset) = value;
588 #endif
589 }
590 
591 static __inline void
592 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
593 		       bus_size_t offset, u_int32_t value)
594 {
595 #if defined(_AMD64_BUS_PIO_H_)
596 #if defined(_AMD64_BUS_MEMIO_H_)
597 	if (tag == AMD64_BUS_SPACE_IO)
598 #endif
599 		outl(bsh + offset, value);
600 #endif
601 #if defined(_AMD64_BUS_MEMIO_H_)
602 #if defined(_AMD64_BUS_PIO_H_)
603 	else
604 #endif
605 		*(volatile u_int32_t *)(bsh + offset) = value;
606 #endif
607 }
608 
609 #if 0	/* Cause a link error for bus_space_write_8 */
610 #define	bus_space_write_8	!!! bus_space_write_8 not implemented !!!
611 #endif
612 
613 /*
614  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
615  * provided to bus space described by tag/handle/offset.
616  */
617 
618 static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
619 					     bus_space_handle_t bsh,
620 					     bus_size_t offset,
621 					     const u_int8_t *addr,
622 					     size_t count);
623 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
624 					     bus_space_handle_t bsh,
625 					     bus_size_t offset,
626 					     const u_int16_t *addr,
627 					     size_t count);
628 
629 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
630 					     bus_space_handle_t bsh,
631 					     bus_size_t offset,
632 					     const u_int32_t *addr,
633 					     size_t count);
634 
635 static __inline void
636 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
637 			bus_size_t offset, const u_int8_t *addr, size_t count)
638 {
639 #if defined(_AMD64_BUS_PIO_H_)
640 #if defined(_AMD64_BUS_MEMIO_H_)
641 	if (tag == AMD64_BUS_SPACE_IO)
642 #endif
643 		outsb(bsh + offset, addr, count);
644 #endif
645 #if defined(_AMD64_BUS_MEMIO_H_)
646 #if defined(_AMD64_BUS_PIO_H_)
647 	else
648 #endif
649 	{
650 #ifdef __GNUCLIKE_ASM
651 		__asm __volatile("				\n\
652 			cld					\n\
653 		1:	lodsb					\n\
654 			movb %%al,(%2)				\n\
655 			loop 1b"				:
656 		    "=S" (addr), "=c" (count)			:
657 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
658 		    "%eax", "memory", "cc");
659 #endif
660 	}
661 #endif
662 }
663 
664 static __inline void
665 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
666 			bus_size_t offset, const u_int16_t *addr, size_t count)
667 {
668 #if defined(_AMD64_BUS_PIO_H_)
669 #if defined(_AMD64_BUS_MEMIO_H_)
670 	if (tag == AMD64_BUS_SPACE_IO)
671 #endif
672 		outsw(bsh + offset, addr, count);
673 #endif
674 #if defined(_AMD64_BUS_MEMIO_H_)
675 #if defined(_AMD64_BUS_PIO_H_)
676 	else
677 #endif
678 	{
679 #ifdef __GNUCLIKE_ASM
680 		__asm __volatile("				\n\
681 			cld					\n\
682 		1:	lodsw					\n\
683 			movw %%ax,(%2)				\n\
684 			loop 1b"				:
685 		    "=S" (addr), "=c" (count)			:
686 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
687 		    "%eax", "memory", "cc");
688 #endif
689 	}
690 #endif
691 }
692 
693 static __inline void
694 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
695 			bus_size_t offset, const u_int32_t *addr, size_t count)
696 {
697 #if defined(_AMD64_BUS_PIO_H_)
698 #if defined(_AMD64_BUS_MEMIO_H_)
699 	if (tag == AMD64_BUS_SPACE_IO)
700 #endif
701 		outsl(bsh + offset, addr, count);
702 #endif
703 #if defined(_AMD64_BUS_MEMIO_H_)
704 #if defined(_AMD64_BUS_PIO_H_)
705 	else
706 #endif
707 	{
708 #ifdef __GNUCLIKE_ASM
709 		__asm __volatile("				\n\
710 			cld					\n\
711 		1:	lodsl					\n\
712 			movl %%eax,(%2)				\n\
713 			loop 1b"				:
714 		    "=S" (addr), "=c" (count)			:
715 		    "r" (bsh + offset), "0" (addr), "1" (count)	:
716 		    "%eax", "memory", "cc");
717 #endif
718 	}
719 #endif
720 }
721 
722 #if 0	/* Cause a link error for bus_space_write_multi_8 */
723 #define	bus_space_write_multi_8(t, h, o, a, c)				\
724 			!!! bus_space_write_multi_8 unimplemented !!!
725 #endif
726 
727 /*
728  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
729  * to bus space described by tag/handle starting at `offset'.
730  */
731 
732 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
733 					      bus_space_handle_t bsh,
734 					      bus_size_t offset,
735 					      const u_int8_t *addr,
736 					      size_t count);
737 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
738 					      bus_space_handle_t bsh,
739 					      bus_size_t offset,
740 					      const u_int16_t *addr,
741 					      size_t count);
742 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
743 					      bus_space_handle_t bsh,
744 					      bus_size_t offset,
745 					      const u_int32_t *addr,
746 					      size_t count);
747 
748 static __inline void
749 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
750 			 bus_size_t offset, const u_int8_t *addr, size_t count)
751 {
752 #if defined(_AMD64_BUS_PIO_H_)
753 #if defined(_AMD64_BUS_MEMIO_H_)
754 	if (tag == AMD64_BUS_SPACE_IO)
755 #endif
756 	{
757 		int _port_ = bsh + offset;
758 #ifdef __GNUCLIKE_ASM
759 		__asm __volatile("				\n\
760 			cld					\n\
761 		1:	lodsb					\n\
762 			outb %%al,%w0				\n\
763 			incl %0					\n\
764 			loop 1b"				:
765 		    "=d" (_port_), "=S" (addr), "=c" (count)	:
766 		    "0" (_port_), "1" (addr), "2" (count)	:
767 		    "%eax", "memory", "cc");
768 #endif
769 	}
770 #endif
771 #if defined(_AMD64_BUS_MEMIO_H_)
772 #if defined(_AMD64_BUS_PIO_H_)
773 	else
774 #endif
775 	{
776 		bus_space_handle_t _port_ = bsh + offset;
777 #ifdef __GNUCLIKE_ASM
778 		__asm __volatile("				\n\
779 			cld					\n\
780 			repne					\n\
781 			movsb"					:
782 		    "=D" (_port_), "=S" (addr), "=c" (count)	:
783 		    "0" (_port_), "1" (addr), "2" (count)	:
784 		    "memory", "cc");
785 #endif
786 	}
787 #endif
788 }
789 
790 static __inline void
791 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
792 			 bus_size_t offset, const u_int16_t *addr, size_t count)
793 {
794 #if defined(_AMD64_BUS_PIO_H_)
795 #if defined(_AMD64_BUS_MEMIO_H_)
796 	if (tag == AMD64_BUS_SPACE_IO)
797 #endif
798 	{
799 		int _port_ = bsh + offset;
800 #ifdef __GNUCLIKE_ASM
801 		__asm __volatile("				\n\
802 			cld					\n\
803 		1:	lodsw					\n\
804 			outw %%ax,%w0				\n\
805 			addl $2,%0				\n\
806 			loop 1b"				:
807 		    "=d" (_port_), "=S" (addr), "=c" (count)	:
808 		    "0" (_port_), "1" (addr), "2" (count)	:
809 		    "%eax", "memory", "cc");
810 #endif
811 	}
812 #endif
813 #if defined(_AMD64_BUS_MEMIO_H_)
814 #if defined(_AMD64_BUS_PIO_H_)
815 	else
816 #endif
817 	{
818 		bus_space_handle_t _port_ = bsh + offset;
819 #ifdef __GNUCLIKE_ASM
820 		__asm __volatile("				\n\
821 			cld					\n\
822 			repne					\n\
823 			movsw"					:
824 		    "=D" (_port_), "=S" (addr), "=c" (count)	:
825 		    "0" (_port_), "1" (addr), "2" (count)	:
826 		    "memory", "cc");
827 #endif
828 	}
829 #endif
830 }
831 
832 static __inline void
833 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
834 			 bus_size_t offset, const u_int32_t *addr, size_t count)
835 {
836 #if defined(_AMD64_BUS_PIO_H_)
837 #if defined(_AMD64_BUS_MEMIO_H_)
838 	if (tag == AMD64_BUS_SPACE_IO)
839 #endif
840 	{
841 		int _port_ = bsh + offset;
842 #ifdef __GNUCLIKE_ASM
843 		__asm __volatile("				\n\
844 			cld					\n\
845 		1:	lodsl					\n\
846 			outl %%eax,%w0				\n\
847 			addl $4,%0				\n\
848 			loop 1b"				:
849 		    "=d" (_port_), "=S" (addr), "=c" (count)	:
850 		    "0" (_port_), "1" (addr), "2" (count)	:
851 		    "%eax", "memory", "cc");
852 #endif
853 	}
854 #endif
855 #if defined(_AMD64_BUS_MEMIO_H_)
856 #if defined(_AMD64_BUS_PIO_H_)
857 	else
858 #endif
859 	{
860 		bus_space_handle_t _port_ = bsh + offset;
861 #ifdef __GNUCLIKE_ASM
862 		__asm __volatile("				\n\
863 			cld					\n\
864 			repne					\n\
865 			movsl"					:
866 		    "=D" (_port_), "=S" (addr), "=c" (count)	:
867 		    "0" (_port_), "1" (addr), "2" (count)	:
868 		    "memory", "cc");
869 #endif
870 	}
871 #endif
872 }
873 
874 #if 0	/* Cause a link error for bus_space_write_region_8 */
875 #define	bus_space_write_region_8					\
876 			!!! bus_space_write_region_8 unimplemented !!!
877 #endif
878 
879 /*
880  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
881  * by tag/handle/offset `count' times.
882  */
883 
884 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
885 					   bus_space_handle_t bsh,
886 					   bus_size_t offset,
887 					   u_int8_t value, size_t count);
888 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
889 					   bus_space_handle_t bsh,
890 					   bus_size_t offset,
891 					   u_int16_t value, size_t count);
892 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
893 					   bus_space_handle_t bsh,
894 					   bus_size_t offset,
895 					   u_int32_t value, size_t count);
896 
897 static __inline void
898 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
899 		      bus_size_t offset, u_int8_t value, size_t count)
900 {
901 	bus_space_handle_t addr = bsh + offset;
902 
903 #if defined(_AMD64_BUS_PIO_H_)
904 #if defined(_AMD64_BUS_MEMIO_H_)
905 	if (tag == AMD64_BUS_SPACE_IO)
906 #endif
907 		while (count--)
908 			outb(addr, value);
909 #endif
910 #if defined(_AMD64_BUS_MEMIO_H_)
911 #if defined(_AMD64_BUS_PIO_H_)
912 	else
913 #endif
914 		while (count--)
915 			*(volatile u_int8_t *)(addr) = value;
916 #endif
917 }
918 
919 static __inline void
920 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
921 		     bus_size_t offset, u_int16_t value, size_t count)
922 {
923 	bus_space_handle_t addr = bsh + offset;
924 
925 #if defined(_AMD64_BUS_PIO_H_)
926 #if defined(_AMD64_BUS_MEMIO_H_)
927 	if (tag == AMD64_BUS_SPACE_IO)
928 #endif
929 		while (count--)
930 			outw(addr, value);
931 #endif
932 #if defined(_AMD64_BUS_MEMIO_H_)
933 #if defined(_AMD64_BUS_PIO_H_)
934 	else
935 #endif
936 		while (count--)
937 			*(volatile u_int16_t *)(addr) = value;
938 #endif
939 }
940 
941 static __inline void
942 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
943 		      bus_size_t offset, u_int32_t value, size_t count)
944 {
945 	bus_space_handle_t addr = bsh + offset;
946 
947 #if defined(_AMD64_BUS_PIO_H_)
948 #if defined(_AMD64_BUS_MEMIO_H_)
949 	if (tag == AMD64_BUS_SPACE_IO)
950 #endif
951 		while (count--)
952 			outl(addr, value);
953 #endif
954 #if defined(_AMD64_BUS_MEMIO_H_)
955 #if defined(_AMD64_BUS_PIO_H_)
956 	else
957 #endif
958 		while (count--)
959 			*(volatile u_int32_t *)(addr) = value;
960 #endif
961 }
962 
963 #if 0	/* Cause a link error for bus_space_set_multi_8 */
964 #define	bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
965 #endif
966 
967 /*
968  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
969  * by tag/handle starting at `offset'.
970  */
971 
972 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
973 					    bus_space_handle_t bsh,
974 					    bus_size_t offset, u_int8_t value,
975 					    size_t count);
976 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
977 					    bus_space_handle_t bsh,
978 					    bus_size_t offset, u_int16_t value,
979 					    size_t count);
980 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
981 					    bus_space_handle_t bsh,
982 					    bus_size_t offset, u_int32_t value,
983 					    size_t count);
984 
985 static __inline void
986 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
987 		       bus_size_t offset, u_int8_t value, size_t count)
988 {
989 	bus_space_handle_t addr = bsh + offset;
990 
991 #if defined(_AMD64_BUS_PIO_H_)
992 #if defined(_AMD64_BUS_MEMIO_H_)
993 	if (tag == AMD64_BUS_SPACE_IO)
994 #endif
995 		for (; count != 0; count--, addr++)
996 			outb(addr, value);
997 #endif
998 #if defined(_AMD64_BUS_MEMIO_H_)
999 #if defined(_AMD64_BUS_PIO_H_)
1000 	else
1001 #endif
1002 		for (; count != 0; count--, addr++)
1003 			*(volatile u_int8_t *)(addr) = value;
1004 #endif
1005 }
1006 
1007 static __inline void
1008 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
1009 		       bus_size_t offset, u_int16_t value, size_t count)
1010 {
1011 	bus_space_handle_t addr = bsh + offset;
1012 
1013 #if defined(_AMD64_BUS_PIO_H_)
1014 #if defined(_AMD64_BUS_MEMIO_H_)
1015 	if (tag == AMD64_BUS_SPACE_IO)
1016 #endif
1017 		for (; count != 0; count--, addr += 2)
1018 			outw(addr, value);
1019 #endif
1020 #if defined(_AMD64_BUS_MEMIO_H_)
1021 #if defined(_AMD64_BUS_PIO_H_)
1022 	else
1023 #endif
1024 		for (; count != 0; count--, addr += 2)
1025 			*(volatile u_int16_t *)(addr) = value;
1026 #endif
1027 }
1028 
1029 static __inline void
1030 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
1031 		       bus_size_t offset, u_int32_t value, size_t count)
1032 {
1033 	bus_space_handle_t addr = bsh + offset;
1034 
1035 #if defined(_AMD64_BUS_PIO_H_)
1036 #if defined(_AMD64_BUS_MEMIO_H_)
1037 	if (tag == AMD64_BUS_SPACE_IO)
1038 #endif
1039 		for (; count != 0; count--, addr += 4)
1040 			outl(addr, value);
1041 #endif
1042 #if defined(_AMD64_BUS_MEMIO_H_)
1043 #if defined(_AMD64_BUS_PIO_H_)
1044 	else
1045 #endif
1046 		for (; count != 0; count--, addr += 4)
1047 			*(volatile u_int32_t *)(addr) = value;
1048 #endif
1049 }
1050 
1051 #if 0	/* Cause a link error for bus_space_set_region_8 */
1052 #define	bus_space_set_region_8	!!! bus_space_set_region_8 unimplemented !!!
1053 #endif
1054 
1055 /*
1056  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
1057  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
1058  */
1059 
1060 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
1061 					     bus_space_handle_t bsh1,
1062 					     bus_size_t off1,
1063 					     bus_space_handle_t bsh2,
1064 					     bus_size_t off2, size_t count);
1065 
1066 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
1067 					     bus_space_handle_t bsh1,
1068 					     bus_size_t off1,
1069 					     bus_space_handle_t bsh2,
1070 					     bus_size_t off2, size_t count);
1071 
1072 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
1073 					     bus_space_handle_t bsh1,
1074 					     bus_size_t off1,
1075 					     bus_space_handle_t bsh2,
1076 					     bus_size_t off2, size_t count);
1077 
1078 static __inline void
1079 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
1080 			bus_size_t off1, bus_space_handle_t bsh2,
1081 			bus_size_t off2, size_t count)
1082 {
1083 	bus_space_handle_t addr1 = bsh1 + off1;
1084 	bus_space_handle_t addr2 = bsh2 + off2;
1085 
1086 #if defined(_AMD64_BUS_PIO_H_)
1087 #if defined(_AMD64_BUS_MEMIO_H_)
1088 	if (tag == AMD64_BUS_SPACE_IO)
1089 #endif
1090 	{
1091 		if (addr1 >= addr2) {
1092 			/* src after dest: copy forward */
1093 			for (; count != 0; count--, addr1++, addr2++)
1094 				outb(addr2, inb(addr1));
1095 		} else {
1096 			/* dest after src: copy backwards */
1097 			for (addr1 += (count - 1), addr2 += (count - 1);
1098 			    count != 0; count--, addr1--, addr2--)
1099 				outb(addr2, inb(addr1));
1100 		}
1101 	}
1102 #endif
1103 #if defined(_AMD64_BUS_MEMIO_H_)
1104 #if defined(_AMD64_BUS_PIO_H_)
1105 	else
1106 #endif
1107 	{
1108 		if (addr1 >= addr2) {
1109 			/* src after dest: copy forward */
1110 			for (; count != 0; count--, addr1++, addr2++)
1111 				*(volatile u_int8_t *)(addr2) =
1112 				    *(volatile u_int8_t *)(addr1);
1113 		} else {
1114 			/* dest after src: copy backwards */
1115 			for (addr1 += (count - 1), addr2 += (count - 1);
1116 			    count != 0; count--, addr1--, addr2--)
1117 				*(volatile u_int8_t *)(addr2) =
1118 				    *(volatile u_int8_t *)(addr1);
1119 		}
1120 	}
1121 #endif
1122 }
1123 
1124 static __inline void
1125 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
1126 			bus_size_t off1, bus_space_handle_t bsh2,
1127 			bus_size_t off2, size_t count)
1128 {
1129 	bus_space_handle_t addr1 = bsh1 + off1;
1130 	bus_space_handle_t addr2 = bsh2 + off2;
1131 
1132 #if defined(_AMD64_BUS_PIO_H_)
1133 #if defined(_AMD64_BUS_MEMIO_H_)
1134 	if (tag == AMD64_BUS_SPACE_IO)
1135 #endif
1136 	{
1137 		if (addr1 >= addr2) {
1138 			/* src after dest: copy forward */
1139 			for (; count != 0; count--, addr1 += 2, addr2 += 2)
1140 				outw(addr2, inw(addr1));
1141 		} else {
1142 			/* dest after src: copy backwards */
1143 			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1144 			    count != 0; count--, addr1 -= 2, addr2 -= 2)
1145 				outw(addr2, inw(addr1));
1146 		}
1147 	}
1148 #endif
1149 #if defined(_AMD64_BUS_MEMIO_H_)
1150 #if defined(_AMD64_BUS_PIO_H_)
1151 	else
1152 #endif
1153 	{
1154 		if (addr1 >= addr2) {
1155 			/* src after dest: copy forward */
1156 			for (; count != 0; count--, addr1 += 2, addr2 += 2)
1157 				*(volatile u_int16_t *)(addr2) =
1158 				    *(volatile u_int16_t *)(addr1);
1159 		} else {
1160 			/* dest after src: copy backwards */
1161 			for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1162 			    count != 0; count--, addr1 -= 2, addr2 -= 2)
1163 				*(volatile u_int16_t *)(addr2) =
1164 				    *(volatile u_int16_t *)(addr1);
1165 		}
1166 	}
1167 #endif
1168 }
1169 
1170 static __inline void
1171 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
1172 			bus_size_t off1, bus_space_handle_t bsh2,
1173 			bus_size_t off2, size_t count)
1174 {
1175 	bus_space_handle_t addr1 = bsh1 + off1;
1176 	bus_space_handle_t addr2 = bsh2 + off2;
1177 
1178 #if defined(_AMD64_BUS_PIO_H_)
1179 #if defined(_AMD64_BUS_MEMIO_H_)
1180 	if (tag == AMD64_BUS_SPACE_IO)
1181 #endif
1182 	{
1183 		if (addr1 >= addr2) {
1184 			/* src after dest: copy forward */
1185 			for (; count != 0; count--, addr1 += 4, addr2 += 4)
1186 				outl(addr2, inl(addr1));
1187 		} else {
1188 			/* dest after src: copy backwards */
1189 			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1190 			    count != 0; count--, addr1 -= 4, addr2 -= 4)
1191 				outl(addr2, inl(addr1));
1192 		}
1193 	}
1194 #endif
1195 #if defined(_AMD64_BUS_MEMIO_H_)
1196 #if defined(_AMD64_BUS_PIO_H_)
1197 	else
1198 #endif
1199 	{
1200 		if (addr1 >= addr2) {
1201 			/* src after dest: copy forward */
1202 			for (; count != 0; count--, addr1 += 4, addr2 += 4)
1203 				*(volatile u_int32_t *)(addr2) =
1204 				    *(volatile u_int32_t *)(addr1);
1205 		} else {
1206 			/* dest after src: copy backwards */
1207 			for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1208 			    count != 0; count--, addr1 -= 4, addr2 -= 4)
1209 				*(volatile u_int32_t *)(addr2) =
1210 				    *(volatile u_int32_t *)(addr1);
1211 		}
1212 	}
1213 #endif
1214 }
1215 
1216 #endif /* defined(_AMD64_BUS_PIO_H_) || defined(_AMD64_MEM_IO_H_) */
1217 
1218 #if 0	/* Cause a link error for bus_space_copy_8 */
1219 #define	bus_space_copy_region_8	!!! bus_space_copy_region_8 unimplemented !!!
1220 #endif
1221 
1222 /*
1223  * Bus read/write barrier methods.
1224  *
1225  *	void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
1226  *			       bus_size_t offset, bus_size_t len, int flags);
1227  *
1228  *
1229  * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
1230  * prevent reordering by the compiler; all Intel x86 processors currently
1231  * retire operations outside the CPU in program order.
1232  */
1233 #define	BUS_SPACE_BARRIER_READ	0x01		/* force read barrier */
1234 #define	BUS_SPACE_BARRIER_WRITE	0x02		/* force write barrier */
1235 
1236 static __inline void
1237 bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
1238 		  bus_size_t offset __unused, bus_size_t len __unused, int flags)
1239 {
1240 #ifdef __GNUCLIKE_ASM
1241 	if (flags & BUS_SPACE_BARRIER_READ)
1242 		__asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
1243 	else
1244 		__asm __volatile("" : : : "memory");
1245 #endif
1246 }
1247 
1248 #include <machine/bus_dma.h>
1249 
1250 /*
1251  * Stream accesses are the same as normal accesses on amd64; there are no
1252  * supported bus systems with an endianess different from the host one.
1253  */
1254 #define	bus_space_read_stream_1(t, h, o)	bus_space_read_1((t), (h), (o))
1255 #define	bus_space_read_stream_2(t, h, o)	bus_space_read_2((t), (h), (o))
1256 #define	bus_space_read_stream_4(t, h, o)	bus_space_read_4((t), (h), (o))
1257 
1258 #define	bus_space_read_multi_stream_1(t, h, o, a, c) \
1259 	bus_space_read_multi_1((t), (h), (o), (a), (c))
1260 #define	bus_space_read_multi_stream_2(t, h, o, a, c) \
1261 	bus_space_read_multi_2((t), (h), (o), (a), (c))
1262 #define	bus_space_read_multi_stream_4(t, h, o, a, c) \
1263 	bus_space_read_multi_4((t), (h), (o), (a), (c))
1264 
1265 #define	bus_space_write_stream_1(t, h, o, v) \
1266 	bus_space_write_1((t), (h), (o), (v))
1267 #define	bus_space_write_stream_2(t, h, o, v) \
1268 	bus_space_write_2((t), (h), (o), (v))
1269 #define	bus_space_write_stream_4(t, h, o, v) \
1270 	bus_space_write_4((t), (h), (o), (v))
1271 
1272 #define	bus_space_write_multi_stream_1(t, h, o, a, c) \
1273 	bus_space_write_multi_1((t), (h), (o), (a), (c))
1274 #define	bus_space_write_multi_stream_2(t, h, o, a, c) \
1275 	bus_space_write_multi_2((t), (h), (o), (a), (c))
1276 #define	bus_space_write_multi_stream_4(t, h, o, a, c) \
1277 	bus_space_write_multi_4((t), (h), (o), (a), (c))
1278 
1279 #define	bus_space_set_multi_stream_1(t, h, o, v, c) \
1280 	bus_space_set_multi_1((t), (h), (o), (v), (c))
1281 #define	bus_space_set_multi_stream_2(t, h, o, v, c) \
1282 	bus_space_set_multi_2((t), (h), (o), (v), (c))
1283 #define	bus_space_set_multi_stream_4(t, h, o, v, c) \
1284 	bus_space_set_multi_4((t), (h), (o), (v), (c))
1285 
1286 #define	bus_space_read_region_stream_1(t, h, o, a, c) \
1287 	bus_space_read_region_1((t), (h), (o), (a), (c))
1288 #define	bus_space_read_region_stream_2(t, h, o, a, c) \
1289 	bus_space_read_region_2((t), (h), (o), (a), (c))
1290 #define	bus_space_read_region_stream_4(t, h, o, a, c) \
1291 	bus_space_read_region_4((t), (h), (o), (a), (c))
1292 
1293 #define	bus_space_write_region_stream_1(t, h, o, a, c) \
1294 	bus_space_write_region_1((t), (h), (o), (a), (c))
1295 #define	bus_space_write_region_stream_2(t, h, o, a, c) \
1296 	bus_space_write_region_2((t), (h), (o), (a), (c))
1297 #define	bus_space_write_region_stream_4(t, h, o, a, c) \
1298 	bus_space_write_region_4((t), (h), (o), (a), (c))
1299 
1300 #define	bus_space_set_region_stream_1(t, h, o, v, c) \
1301 	bus_space_set_region_1((t), (h), (o), (v), (c))
1302 #define	bus_space_set_region_stream_2(t, h, o, v, c) \
1303 	bus_space_set_region_2((t), (h), (o), (v), (c))
1304 #define	bus_space_set_region_stream_4(t, h, o, v, c) \
1305 	bus_space_set_region_4((t), (h), (o), (v), (c))
1306 
1307 #define	bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
1308 	bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
1309 #define	bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
1310 	bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
1311 #define	bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
1312 	bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
1313 
1314 #endif /* _AMD64_BUS_H_ */
1315