2 * Copyright (c) 2005 Scott Long
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * $DragonFly: src/sys/cpu/amd64/include/bus_dma.h,v 1.1 2007/09/23 04:29:30 yanyh Exp $
29 #ifndef _CPU_BUS_DMA_H_
30 #define _CPU_BUS_DMA_H_
32 #include <machine/cpufunc.h>
35 * Bus address and size types
38 typedef uint64_t bus_addr_t;
39 typedef uint64_t bus_size_t;
41 typedef uint64_t bus_space_tag_t;
42 typedef uint64_t bus_space_handle_t;
44 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
45 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
46 #define BUS_SPACE_MAXSIZE (64 * 1024) /* Maximum supported size */
47 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
48 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
49 #define BUS_SPACE_MAXADDR BUS_SPACE_MAXADDR_32BIT
51 #define BUS_SPACE_UNRESTRICTED (~0)
54 * Values for the amd64 bus space tag, not to be used directly by MI code.
56 #define AMD64_BUS_SPACE_IO 0 /* space is i/o space */
57 #define AMD64_BUS_SPACE_MEM 1 /* space is mem space */
60 * Map a region of device bus space into CPU virtual address space.
63 static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
64 bus_size_t size, int flags,
65 bus_space_handle_t *bshp);
68 bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
69 bus_size_t size __unused, int flags __unused,
70 bus_space_handle_t *bshp)
78 * Unmap a region of device bus space.
81 static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
85 bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
86 bus_size_t size __unused)
91 * Get a new handle for a subregion of an already-mapped area of bus space.
94 static __inline int bus_space_subregion(bus_space_tag_t t,
95 bus_space_handle_t bsh,
96 bus_size_t offset, bus_size_t size,
97 bus_space_handle_t *nbshp);
100 bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
101 bus_size_t offset, bus_size_t size __unused,
102 bus_space_handle_t *nbshp)
105 *nbshp = bsh + offset;
109 static __inline void *
110 bus_space_kva(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset)
112 if (tag == AMD64_BUS_SPACE_IO)
114 return ((void *)(handle + offset));
118 * Allocate a region of memory that is accessible to devices in bus space.
121 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
122 bus_addr_t rend, bus_size_t size, bus_size_t align,
123 bus_size_t boundary, int flags, bus_addr_t *addrp,
124 bus_space_handle_t *bshp);
127 * Free a region of bus space accessible memory.
130 static __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
134 bus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
135 bus_size_t size __unused)
141 * Read a 1, 2, 4, or 8 byte quantity from bus space
142 * described by tag/handle/offset.
144 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
145 bus_space_handle_t handle,
148 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
149 bus_space_handle_t handle,
152 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
153 bus_space_handle_t handle,
156 static __inline u_int8_t
157 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
161 if (tag == AMD64_BUS_SPACE_IO)
162 return (inb(handle + offset));
163 return (*(volatile u_int8_t *)(handle + offset));
166 static __inline u_int16_t
167 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
171 if (tag == AMD64_BUS_SPACE_IO)
172 return (inw(handle + offset));
173 return (*(volatile u_int16_t *)(handle + offset));
176 static __inline u_int32_t
177 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
181 if (tag == AMD64_BUS_SPACE_IO)
182 return (inl(handle + offset));
183 return (*(volatile u_int32_t *)(handle + offset));
186 #if 0 /* Cause a link error for bus_space_read_8 */
187 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
191 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
192 * described by tag/handle/offset and copy into buffer provided.
194 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
195 bus_space_handle_t bsh,
196 bus_size_t offset, u_int8_t *addr,
199 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
200 bus_space_handle_t bsh,
201 bus_size_t offset, u_int16_t *addr,
204 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
205 bus_space_handle_t bsh,
206 bus_size_t offset, u_int32_t *addr,
210 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
211 bus_size_t offset, u_int8_t *addr, size_t count)
214 if (tag == AMD64_BUS_SPACE_IO)
215 insb(bsh + offset, addr, count);
217 __asm __volatile(" \n\
219 1: movb (%2),%%al \n\
222 "=D" (addr), "=c" (count) :
223 "r" (bsh + offset), "0" (addr), "1" (count) :
229 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
230 bus_size_t offset, u_int16_t *addr, size_t count)
233 if (tag == AMD64_BUS_SPACE_IO)
234 insw(bsh + offset, addr, count);
236 __asm __volatile(" \n\
238 1: movw (%2),%%ax \n\
241 "=D" (addr), "=c" (count) :
242 "r" (bsh + offset), "0" (addr), "1" (count) :
248 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
249 bus_size_t offset, u_int32_t *addr, size_t count)
252 if (tag == AMD64_BUS_SPACE_IO)
253 insl(bsh + offset, addr, count);
255 __asm __volatile(" \n\
257 1: movl (%2),%%eax \n\
260 "=D" (addr), "=c" (count) :
261 "r" (bsh + offset), "0" (addr), "1" (count) :
266 #if 0 /* Cause a link error for bus_space_read_multi_8 */
267 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
271 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
272 * described by tag/handle and starting at `offset' and copy into
275 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
276 bus_space_handle_t bsh,
277 bus_size_t offset, u_int8_t *addr,
280 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
281 bus_space_handle_t bsh,
282 bus_size_t offset, u_int16_t *addr,
285 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
286 bus_space_handle_t bsh,
287 bus_size_t offset, u_int32_t *addr,
292 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
293 bus_size_t offset, u_int8_t *addr, size_t count)
296 if (tag == AMD64_BUS_SPACE_IO) {
297 int _port_ = bsh + offset;
298 __asm __volatile(" \n\
304 "=D" (addr), "=c" (count), "=d" (_port_) :
305 "0" (addr), "1" (count), "2" (_port_) :
306 "%eax", "memory", "cc");
308 bus_space_handle_t _port_ = bsh + offset;
309 __asm __volatile(" \n\
313 "=D" (addr), "=c" (count), "=S" (_port_) :
314 "0" (addr), "1" (count), "2" (_port_) :
320 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
321 bus_size_t offset, u_int16_t *addr, size_t count)
324 if (tag == AMD64_BUS_SPACE_IO) {
325 int _port_ = bsh + offset;
326 __asm __volatile(" \n\
332 "=D" (addr), "=c" (count), "=d" (_port_) :
333 "0" (addr), "1" (count), "2" (_port_) :
334 "%eax", "memory", "cc");
336 bus_space_handle_t _port_ = bsh + offset;
337 __asm __volatile(" \n\
341 "=D" (addr), "=c" (count), "=S" (_port_) :
342 "0" (addr), "1" (count), "2" (_port_) :
348 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
349 bus_size_t offset, u_int32_t *addr, size_t count)
352 if (tag == AMD64_BUS_SPACE_IO) {
353 int _port_ = bsh + offset;
354 __asm __volatile(" \n\
360 "=D" (addr), "=c" (count), "=d" (_port_) :
361 "0" (addr), "1" (count), "2" (_port_) :
362 "%eax", "memory", "cc");
364 bus_space_handle_t _port_ = bsh + offset;
365 __asm __volatile(" \n\
369 "=D" (addr), "=c" (count), "=S" (_port_) :
370 "0" (addr), "1" (count), "2" (_port_) :
375 #if 0 /* Cause a link error for bus_space_read_region_8 */
376 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
380 * Write the 1, 2, 4, or 8 byte value `value' to bus space
381 * described by tag/handle/offset.
384 static __inline void bus_space_write_1(bus_space_tag_t tag,
385 bus_space_handle_t bsh,
386 bus_size_t offset, u_int8_t value);
388 static __inline void bus_space_write_2(bus_space_tag_t tag,
389 bus_space_handle_t bsh,
390 bus_size_t offset, u_int16_t value);
392 static __inline void bus_space_write_4(bus_space_tag_t tag,
393 bus_space_handle_t bsh,
394 bus_size_t offset, u_int32_t value);
397 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
398 bus_size_t offset, u_int8_t value)
401 if (tag == AMD64_BUS_SPACE_IO)
402 outb(bsh + offset, value);
404 *(volatile u_int8_t *)(bsh + offset) = value;
408 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
409 bus_size_t offset, u_int16_t value)
412 if (tag == AMD64_BUS_SPACE_IO)
413 outw(bsh + offset, value);
415 *(volatile u_int16_t *)(bsh + offset) = value;
419 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
420 bus_size_t offset, u_int32_t value)
423 if (tag == AMD64_BUS_SPACE_IO)
424 outl(bsh + offset, value);
426 *(volatile u_int32_t *)(bsh + offset) = value;
429 #if 0 /* Cause a link error for bus_space_write_8 */
430 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
434 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
435 * provided to bus space described by tag/handle/offset.
438 static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
439 bus_space_handle_t bsh,
441 const u_int8_t *addr,
443 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
444 bus_space_handle_t bsh,
446 const u_int16_t *addr,
449 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
450 bus_space_handle_t bsh,
452 const u_int32_t *addr,
456 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
457 bus_size_t offset, const u_int8_t *addr, size_t count)
460 if (tag == AMD64_BUS_SPACE_IO)
461 outsb(bsh + offset, addr, count);
463 __asm __volatile(" \n\
468 "=S" (addr), "=c" (count) :
469 "r" (bsh + offset), "0" (addr), "1" (count) :
470 "%eax", "memory", "cc");
475 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
476 bus_size_t offset, const u_int16_t *addr, size_t count)
479 if (tag == AMD64_BUS_SPACE_IO)
480 outsw(bsh + offset, addr, count);
482 __asm __volatile(" \n\
487 "=S" (addr), "=c" (count) :
488 "r" (bsh + offset), "0" (addr), "1" (count) :
489 "%eax", "memory", "cc");
494 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
495 bus_size_t offset, const u_int32_t *addr, size_t count)
498 if (tag == AMD64_BUS_SPACE_IO)
499 outsl(bsh + offset, addr, count);
501 __asm __volatile(" \n\
506 "=S" (addr), "=c" (count) :
507 "r" (bsh + offset), "0" (addr), "1" (count) :
508 "%eax", "memory", "cc");
512 #if 0 /* Cause a link error for bus_space_write_multi_8 */
513 #define bus_space_write_multi_8(t, h, o, a, c) \
514 !!! bus_space_write_multi_8 unimplemented !!!
518 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
519 * to bus space described by tag/handle starting at `offset'.
522 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
523 bus_space_handle_t bsh,
525 const u_int8_t *addr,
527 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
528 bus_space_handle_t bsh,
530 const u_int16_t *addr,
532 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
533 bus_space_handle_t bsh,
535 const u_int32_t *addr,
539 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
540 bus_size_t offset, const u_int8_t *addr, size_t count)
543 if (tag == AMD64_BUS_SPACE_IO) {
544 int _port_ = bsh + offset;
545 __asm __volatile(" \n\
551 "=d" (_port_), "=S" (addr), "=c" (count) :
552 "0" (_port_), "1" (addr), "2" (count) :
553 "%eax", "memory", "cc");
555 bus_space_handle_t _port_ = bsh + offset;
556 __asm __volatile(" \n\
560 "=D" (_port_), "=S" (addr), "=c" (count) :
561 "0" (_port_), "1" (addr), "2" (count) :
567 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
568 bus_size_t offset, const u_int16_t *addr, size_t count)
571 if (tag == AMD64_BUS_SPACE_IO) {
572 int _port_ = bsh + offset;
573 __asm __volatile(" \n\
579 "=d" (_port_), "=S" (addr), "=c" (count) :
580 "0" (_port_), "1" (addr), "2" (count) :
581 "%eax", "memory", "cc");
583 bus_space_handle_t _port_ = bsh + offset;
584 __asm __volatile(" \n\
588 "=D" (_port_), "=S" (addr), "=c" (count) :
589 "0" (_port_), "1" (addr), "2" (count) :
595 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
596 bus_size_t offset, const u_int32_t *addr, size_t count)
599 if (tag == AMD64_BUS_SPACE_IO) {
600 int _port_ = bsh + offset;
601 __asm __volatile(" \n\
607 "=d" (_port_), "=S" (addr), "=c" (count) :
608 "0" (_port_), "1" (addr), "2" (count) :
609 "%eax", "memory", "cc");
611 bus_space_handle_t _port_ = bsh + offset;
612 __asm __volatile(" \n\
616 "=D" (_port_), "=S" (addr), "=c" (count) :
617 "0" (_port_), "1" (addr), "2" (count) :
622 #if 0 /* Cause a link error for bus_space_write_region_8 */
623 #define bus_space_write_region_8 \
624 !!! bus_space_write_region_8 unimplemented !!!
628 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
629 * by tag/handle/offset `count' times.
632 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
633 bus_space_handle_t bsh,
635 u_int8_t value, size_t count);
636 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
637 bus_space_handle_t bsh,
639 u_int16_t value, size_t count);
640 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
641 bus_space_handle_t bsh,
643 u_int32_t value, size_t count);
646 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
647 bus_size_t offset, u_int8_t value, size_t count)
649 bus_space_handle_t addr = bsh + offset;
651 if (tag == AMD64_BUS_SPACE_IO)
656 *(volatile u_int8_t *)(addr) = value;
660 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
661 bus_size_t offset, u_int16_t value, size_t count)
663 bus_space_handle_t addr = bsh + offset;
665 if (tag == AMD64_BUS_SPACE_IO)
670 *(volatile u_int16_t *)(addr) = value;
674 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
675 bus_size_t offset, u_int32_t value, size_t count)
677 bus_space_handle_t addr = bsh + offset;
679 if (tag == AMD64_BUS_SPACE_IO)
684 *(volatile u_int32_t *)(addr) = value;
687 #if 0 /* Cause a link error for bus_space_set_multi_8 */
688 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
692 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
693 * by tag/handle starting at `offset'.
696 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
697 bus_space_handle_t bsh,
698 bus_size_t offset, u_int8_t value,
700 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
701 bus_space_handle_t bsh,
702 bus_size_t offset, u_int16_t value,
704 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
705 bus_space_handle_t bsh,
706 bus_size_t offset, u_int32_t value,
710 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
711 bus_size_t offset, u_int8_t value, size_t count)
713 bus_space_handle_t addr = bsh + offset;
715 if (tag == AMD64_BUS_SPACE_IO)
716 for (; count != 0; count--, addr++)
719 for (; count != 0; count--, addr++)
720 *(volatile u_int8_t *)(addr) = value;
724 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
725 bus_size_t offset, u_int16_t value, size_t count)
727 bus_space_handle_t addr = bsh + offset;
729 if (tag == AMD64_BUS_SPACE_IO)
730 for (; count != 0; count--, addr += 2)
733 for (; count != 0; count--, addr += 2)
734 *(volatile u_int16_t *)(addr) = value;
738 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
739 bus_size_t offset, u_int32_t value, size_t count)
741 bus_space_handle_t addr = bsh + offset;
743 if (tag == AMD64_BUS_SPACE_IO)
744 for (; count != 0; count--, addr += 4)
747 for (; count != 0; count--, addr += 4)
748 *(volatile u_int32_t *)(addr) = value;
751 #if 0 /* Cause a link error for bus_space_set_region_8 */
752 #define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
756 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
757 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
760 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
761 bus_space_handle_t bsh1,
763 bus_space_handle_t bsh2,
764 bus_size_t off2, size_t count);
766 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
767 bus_space_handle_t bsh1,
769 bus_space_handle_t bsh2,
770 bus_size_t off2, size_t count);
772 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
773 bus_space_handle_t bsh1,
775 bus_space_handle_t bsh2,
776 bus_size_t off2, size_t count);
779 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
780 bus_size_t off1, bus_space_handle_t bsh2,
781 bus_size_t off2, size_t count)
783 bus_space_handle_t addr1 = bsh1 + off1;
784 bus_space_handle_t addr2 = bsh2 + off2;
786 if (tag == AMD64_BUS_SPACE_IO) {
787 if (addr1 >= addr2) {
788 /* src after dest: copy forward */
789 for (; count != 0; count--, addr1++, addr2++)
790 outb(addr2, inb(addr1));
792 /* dest after src: copy backwards */
793 for (addr1 += (count - 1), addr2 += (count - 1);
794 count != 0; count--, addr1--, addr2--)
795 outb(addr2, inb(addr1));
798 if (addr1 >= addr2) {
799 /* src after dest: copy forward */
800 for (; count != 0; count--, addr1++, addr2++)
801 *(volatile u_int8_t *)(addr2) =
802 *(volatile u_int8_t *)(addr1);
804 /* dest after src: copy backwards */
805 for (addr1 += (count - 1), addr2 += (count - 1);
806 count != 0; count--, addr1--, addr2--)
807 *(volatile u_int8_t *)(addr2) =
808 *(volatile u_int8_t *)(addr1);
814 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
815 bus_size_t off1, bus_space_handle_t bsh2,
816 bus_size_t off2, size_t count)
818 bus_space_handle_t addr1 = bsh1 + off1;
819 bus_space_handle_t addr2 = bsh2 + off2;
821 if (tag == AMD64_BUS_SPACE_IO) {
822 if (addr1 >= addr2) {
823 /* src after dest: copy forward */
824 for (; count != 0; count--, addr1 += 2, addr2 += 2)
825 outw(addr2, inw(addr1));
827 /* dest after src: copy backwards */
828 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
829 count != 0; count--, addr1 -= 2, addr2 -= 2)
830 outw(addr2, inw(addr1));
833 if (addr1 >= addr2) {
834 /* src after dest: copy forward */
835 for (; count != 0; count--, addr1 += 2, addr2 += 2)
836 *(volatile u_int16_t *)(addr2) =
837 *(volatile u_int16_t *)(addr1);
839 /* dest after src: copy backwards */
840 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
841 count != 0; count--, addr1 -= 2, addr2 -= 2)
842 *(volatile u_int16_t *)(addr2) =
843 *(volatile u_int16_t *)(addr1);
849 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
850 bus_size_t off1, bus_space_handle_t bsh2,
851 bus_size_t off2, size_t count)
853 bus_space_handle_t addr1 = bsh1 + off1;
854 bus_space_handle_t addr2 = bsh2 + off2;
856 if (tag == AMD64_BUS_SPACE_IO) {
857 if (addr1 >= addr2) {
858 /* src after dest: copy forward */
859 for (; count != 0; count--, addr1 += 4, addr2 += 4)
860 outl(addr2, inl(addr1));
862 /* dest after src: copy backwards */
863 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
864 count != 0; count--, addr1 -= 4, addr2 -= 4)
865 outl(addr2, inl(addr1));
868 if (addr1 >= addr2) {
869 /* src after dest: copy forward */
870 for (; count != 0; count--, addr1 += 4, addr2 += 4)
871 *(volatile u_int32_t *)(addr2) =
872 *(volatile u_int32_t *)(addr1);
874 /* dest after src: copy backwards */
875 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
876 count != 0; count--, addr1 -= 4, addr2 -= 4)
877 *(volatile u_int32_t *)(addr2) =
878 *(volatile u_int32_t *)(addr1);
883 #if 0 /* Cause a link error for bus_space_copy_8 */
884 #define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
888 * Bus read/write barrier methods.
890 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
891 * bus_size_t offset, bus_size_t len, int flags);
894 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
895 * prevent reordering by the compiler; all Intel x86 processors currently
896 * retire operations outside the CPU in program order.
898 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
899 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
902 bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
903 bus_size_t offset __unused, bus_size_t len __unused, int flags)
905 if (flags & BUS_SPACE_BARRIER_READ)
906 __asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
908 __asm __volatile("" : : : "memory");
912 * Stream accesses are the same as normal accesses on amd64; there are no
913 * supported bus systems with an endianess different from the host one.
915 #define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o))
916 #define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o))
917 #define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o))
919 #define bus_space_read_multi_stream_1(t, h, o, a, c) \
920 bus_space_read_multi_1((t), (h), (o), (a), (c))
921 #define bus_space_read_multi_stream_2(t, h, o, a, c) \
922 bus_space_read_multi_2((t), (h), (o), (a), (c))
923 #define bus_space_read_multi_stream_4(t, h, o, a, c) \
924 bus_space_read_multi_4((t), (h), (o), (a), (c))
926 #define bus_space_write_stream_1(t, h, o, v) \
927 bus_space_write_1((t), (h), (o), (v))
928 #define bus_space_write_stream_2(t, h, o, v) \
929 bus_space_write_2((t), (h), (o), (v))
930 #define bus_space_write_stream_4(t, h, o, v) \
931 bus_space_write_4((t), (h), (o), (v))
933 #define bus_space_write_multi_stream_1(t, h, o, a, c) \
934 bus_space_write_multi_1((t), (h), (o), (a), (c))
935 #define bus_space_write_multi_stream_2(t, h, o, a, c) \
936 bus_space_write_multi_2((t), (h), (o), (a), (c))
937 #define bus_space_write_multi_stream_4(t, h, o, a, c) \
938 bus_space_write_multi_4((t), (h), (o), (a), (c))
940 #define bus_space_set_multi_stream_1(t, h, o, v, c) \
941 bus_space_set_multi_1((t), (h), (o), (v), (c))
942 #define bus_space_set_multi_stream_2(t, h, o, v, c) \
943 bus_space_set_multi_2((t), (h), (o), (v), (c))
944 #define bus_space_set_multi_stream_4(t, h, o, v, c) \
945 bus_space_set_multi_4((t), (h), (o), (v), (c))
947 #define bus_space_read_region_stream_1(t, h, o, a, c) \
948 bus_space_read_region_1((t), (h), (o), (a), (c))
949 #define bus_space_read_region_stream_2(t, h, o, a, c) \
950 bus_space_read_region_2((t), (h), (o), (a), (c))
951 #define bus_space_read_region_stream_4(t, h, o, a, c) \
952 bus_space_read_region_4((t), (h), (o), (a), (c))
954 #define bus_space_write_region_stream_1(t, h, o, a, c) \
955 bus_space_write_region_1((t), (h), (o), (a), (c))
956 #define bus_space_write_region_stream_2(t, h, o, a, c) \
957 bus_space_write_region_2((t), (h), (o), (a), (c))
958 #define bus_space_write_region_stream_4(t, h, o, a, c) \
959 bus_space_write_region_4((t), (h), (o), (a), (c))
961 #define bus_space_set_region_stream_1(t, h, o, v, c) \
962 bus_space_set_region_1((t), (h), (o), (v), (c))
963 #define bus_space_set_region_stream_2(t, h, o, v, c) \
964 bus_space_set_region_2((t), (h), (o), (v), (c))
965 #define bus_space_set_region_stream_4(t, h, o, v, c) \
966 bus_space_set_region_4((t), (h), (o), (v), (c))
968 #define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
969 bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
970 #define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
971 bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
972 #define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
973 bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
975 #endif /* _CPU_BUS_DMA_H_ */