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