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
27 #ifndef _CPU_BUS_DMA_H_
28 #define _CPU_BUS_DMA_H_
30 #include <machine/cpufunc.h>
33 * Bus address and size types
36 typedef uint64_t bus_addr_t;
37 typedef uint64_t bus_size_t;
39 typedef uint64_t bus_space_tag_t;
40 typedef uint64_t bus_space_handle_t;
42 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
43 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
44 #define BUS_SPACE_MAXSIZE (64 * 1024) /* Maximum supported size */
45 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
46 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
47 #define BUS_SPACE_MAXADDR BUS_SPACE_MAXADDR_32BIT
49 #define BUS_SPACE_UNRESTRICTED (~0)
52 * Values for the amd64 bus space tag, not to be used directly by MI code.
54 #define X86_64_BUS_SPACE_IO 0 /* space is i/o space */
55 #define X86_64_BUS_SPACE_MEM 1 /* space is mem space */
58 * Map a region of device bus space into CPU virtual address space.
61 static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
62 bus_size_t size, int flags,
63 bus_space_handle_t *bshp);
66 bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
67 bus_size_t size __unused, int flags __unused,
68 bus_space_handle_t *bshp)
76 * Unmap a region of device bus space.
79 static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
83 bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
84 bus_size_t size __unused)
89 * Get a new handle for a subregion of an already-mapped area of bus space.
92 static __inline int bus_space_subregion(bus_space_tag_t t,
93 bus_space_handle_t bsh,
94 bus_size_t offset, bus_size_t size,
95 bus_space_handle_t *nbshp);
98 bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
99 bus_size_t offset, bus_size_t size __unused,
100 bus_space_handle_t *nbshp)
103 *nbshp = bsh + offset;
107 static __inline void *
108 bus_space_kva(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t offset)
110 if (tag == X86_64_BUS_SPACE_IO)
112 return ((void *)(handle + offset));
116 * Allocate a region of memory that is accessible to devices in bus space.
119 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
120 bus_addr_t rend, bus_size_t size, bus_size_t align,
121 bus_size_t boundary, int flags, bus_addr_t *addrp,
122 bus_space_handle_t *bshp);
125 * Free a region of bus space accessible memory.
128 static __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
132 bus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
133 bus_size_t size __unused)
139 * Read a 1, 2, 4, or 8 byte quantity from bus space
140 * described by tag/handle/offset.
142 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
143 bus_space_handle_t handle,
146 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
147 bus_space_handle_t handle,
150 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
151 bus_space_handle_t handle,
154 static __inline u_int8_t
155 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
159 if (tag == X86_64_BUS_SPACE_IO)
160 return (inb(handle + offset));
161 return (*(volatile u_int8_t *)(handle + offset));
164 static __inline u_int16_t
165 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
169 if (tag == X86_64_BUS_SPACE_IO)
170 return (inw(handle + offset));
171 return (*(volatile u_int16_t *)(handle + offset));
174 static __inline u_int32_t
175 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
179 if (tag == X86_64_BUS_SPACE_IO)
180 return (inl(handle + offset));
181 return (*(volatile u_int32_t *)(handle + offset));
184 #if 0 /* Cause a link error for bus_space_read_8 */
185 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
189 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
190 * described by tag/handle/offset and copy into buffer provided.
192 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
193 bus_space_handle_t bsh,
194 bus_size_t offset, u_int8_t *addr,
197 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
198 bus_space_handle_t bsh,
199 bus_size_t offset, u_int16_t *addr,
202 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
203 bus_space_handle_t bsh,
204 bus_size_t offset, u_int32_t *addr,
208 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
209 bus_size_t offset, u_int8_t *addr, size_t count)
212 if (tag == X86_64_BUS_SPACE_IO)
213 insb(bsh + offset, addr, count);
215 __asm __volatile(" \n\
217 1: movb (%2),%%al \n\
220 "=D" (addr), "=c" (count) :
221 "r" (bsh + offset), "0" (addr), "1" (count) :
227 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
228 bus_size_t offset, u_int16_t *addr, size_t count)
231 if (tag == X86_64_BUS_SPACE_IO)
232 insw(bsh + offset, addr, count);
234 __asm __volatile(" \n\
236 1: movw (%2),%%ax \n\
239 "=D" (addr), "=c" (count) :
240 "r" (bsh + offset), "0" (addr), "1" (count) :
246 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
247 bus_size_t offset, u_int32_t *addr, size_t count)
250 if (tag == X86_64_BUS_SPACE_IO)
251 insl(bsh + offset, addr, count);
253 __asm __volatile(" \n\
255 1: movl (%2),%%eax \n\
258 "=D" (addr), "=c" (count) :
259 "r" (bsh + offset), "0" (addr), "1" (count) :
264 #if 0 /* Cause a link error for bus_space_read_multi_8 */
265 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
269 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
270 * described by tag/handle and starting at `offset' and copy into
273 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
274 bus_space_handle_t bsh,
275 bus_size_t offset, u_int8_t *addr,
278 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
279 bus_space_handle_t bsh,
280 bus_size_t offset, u_int16_t *addr,
283 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
284 bus_space_handle_t bsh,
285 bus_size_t offset, u_int32_t *addr,
290 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
291 bus_size_t offset, u_int8_t *addr, size_t count)
294 if (tag == X86_64_BUS_SPACE_IO) {
295 int _port_ = bsh + offset;
296 __asm __volatile(" \n\
302 "=D" (addr), "=c" (count), "=d" (_port_) :
303 "0" (addr), "1" (count), "2" (_port_) :
304 "%eax", "memory", "cc");
306 bus_space_handle_t _port_ = bsh + offset;
307 __asm __volatile(" \n\
311 "=D" (addr), "=c" (count), "=S" (_port_) :
312 "0" (addr), "1" (count), "2" (_port_) :
318 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
319 bus_size_t offset, u_int16_t *addr, size_t count)
322 if (tag == X86_64_BUS_SPACE_IO) {
323 int _port_ = bsh + offset;
324 __asm __volatile(" \n\
330 "=D" (addr), "=c" (count), "=d" (_port_) :
331 "0" (addr), "1" (count), "2" (_port_) :
332 "%eax", "memory", "cc");
334 bus_space_handle_t _port_ = bsh + offset;
335 __asm __volatile(" \n\
339 "=D" (addr), "=c" (count), "=S" (_port_) :
340 "0" (addr), "1" (count), "2" (_port_) :
346 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
347 bus_size_t offset, u_int32_t *addr, size_t count)
350 if (tag == X86_64_BUS_SPACE_IO) {
351 int _port_ = bsh + offset;
352 __asm __volatile(" \n\
358 "=D" (addr), "=c" (count), "=d" (_port_) :
359 "0" (addr), "1" (count), "2" (_port_) :
360 "%eax", "memory", "cc");
362 bus_space_handle_t _port_ = bsh + offset;
363 __asm __volatile(" \n\
367 "=D" (addr), "=c" (count), "=S" (_port_) :
368 "0" (addr), "1" (count), "2" (_port_) :
373 #if 0 /* Cause a link error for bus_space_read_region_8 */
374 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
378 * Write the 1, 2, 4, or 8 byte value `value' to bus space
379 * described by tag/handle/offset.
382 static __inline void bus_space_write_1(bus_space_tag_t tag,
383 bus_space_handle_t bsh,
384 bus_size_t offset, u_int8_t value);
386 static __inline void bus_space_write_2(bus_space_tag_t tag,
387 bus_space_handle_t bsh,
388 bus_size_t offset, u_int16_t value);
390 static __inline void bus_space_write_4(bus_space_tag_t tag,
391 bus_space_handle_t bsh,
392 bus_size_t offset, u_int32_t value);
395 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
396 bus_size_t offset, u_int8_t value)
399 if (tag == X86_64_BUS_SPACE_IO)
400 outb(bsh + offset, value);
402 *(volatile u_int8_t *)(bsh + offset) = value;
406 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
407 bus_size_t offset, u_int16_t value)
410 if (tag == X86_64_BUS_SPACE_IO)
411 outw(bsh + offset, value);
413 *(volatile u_int16_t *)(bsh + offset) = value;
417 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
418 bus_size_t offset, u_int32_t value)
421 if (tag == X86_64_BUS_SPACE_IO)
422 outl(bsh + offset, value);
424 *(volatile u_int32_t *)(bsh + offset) = value;
427 #if 0 /* Cause a link error for bus_space_write_8 */
428 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
432 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
433 * provided to bus space described by tag/handle/offset.
436 static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
437 bus_space_handle_t bsh,
439 const u_int8_t *addr,
441 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
442 bus_space_handle_t bsh,
444 const u_int16_t *addr,
447 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
448 bus_space_handle_t bsh,
450 const u_int32_t *addr,
454 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
455 bus_size_t offset, const u_int8_t *addr, size_t count)
458 if (tag == X86_64_BUS_SPACE_IO)
459 outsb(bsh + offset, addr, count);
461 __asm __volatile(" \n\
466 "=S" (addr), "=c" (count) :
467 "r" (bsh + offset), "0" (addr), "1" (count) :
468 "%eax", "memory", "cc");
473 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
474 bus_size_t offset, const u_int16_t *addr, size_t count)
477 if (tag == X86_64_BUS_SPACE_IO)
478 outsw(bsh + offset, addr, count);
480 __asm __volatile(" \n\
485 "=S" (addr), "=c" (count) :
486 "r" (bsh + offset), "0" (addr), "1" (count) :
487 "%eax", "memory", "cc");
492 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
493 bus_size_t offset, const u_int32_t *addr, size_t count)
496 if (tag == X86_64_BUS_SPACE_IO)
497 outsl(bsh + offset, addr, count);
499 __asm __volatile(" \n\
504 "=S" (addr), "=c" (count) :
505 "r" (bsh + offset), "0" (addr), "1" (count) :
506 "%eax", "memory", "cc");
510 #if 0 /* Cause a link error for bus_space_write_multi_8 */
511 #define bus_space_write_multi_8(t, h, o, a, c) \
512 !!! bus_space_write_multi_8 unimplemented !!!
516 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
517 * to bus space described by tag/handle starting at `offset'.
520 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
521 bus_space_handle_t bsh,
523 const u_int8_t *addr,
525 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
526 bus_space_handle_t bsh,
528 const u_int16_t *addr,
530 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
531 bus_space_handle_t bsh,
533 const u_int32_t *addr,
537 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
538 bus_size_t offset, const u_int8_t *addr, size_t count)
541 if (tag == X86_64_BUS_SPACE_IO) {
542 int _port_ = bsh + offset;
543 __asm __volatile(" \n\
549 "=d" (_port_), "=S" (addr), "=c" (count) :
550 "0" (_port_), "1" (addr), "2" (count) :
551 "%eax", "memory", "cc");
553 bus_space_handle_t _port_ = bsh + offset;
554 __asm __volatile(" \n\
558 "=D" (_port_), "=S" (addr), "=c" (count) :
559 "0" (_port_), "1" (addr), "2" (count) :
565 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
566 bus_size_t offset, const u_int16_t *addr, size_t count)
569 if (tag == X86_64_BUS_SPACE_IO) {
570 int _port_ = bsh + offset;
571 __asm __volatile(" \n\
577 "=d" (_port_), "=S" (addr), "=c" (count) :
578 "0" (_port_), "1" (addr), "2" (count) :
579 "%eax", "memory", "cc");
581 bus_space_handle_t _port_ = bsh + offset;
582 __asm __volatile(" \n\
586 "=D" (_port_), "=S" (addr), "=c" (count) :
587 "0" (_port_), "1" (addr), "2" (count) :
593 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
594 bus_size_t offset, const u_int32_t *addr, size_t count)
597 if (tag == X86_64_BUS_SPACE_IO) {
598 int _port_ = bsh + offset;
599 __asm __volatile(" \n\
605 "=d" (_port_), "=S" (addr), "=c" (count) :
606 "0" (_port_), "1" (addr), "2" (count) :
607 "%eax", "memory", "cc");
609 bus_space_handle_t _port_ = bsh + offset;
610 __asm __volatile(" \n\
614 "=D" (_port_), "=S" (addr), "=c" (count) :
615 "0" (_port_), "1" (addr), "2" (count) :
620 #if 0 /* Cause a link error for bus_space_write_region_8 */
621 #define bus_space_write_region_8 \
622 !!! bus_space_write_region_8 unimplemented !!!
626 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
627 * by tag/handle/offset `count' times.
630 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
631 bus_space_handle_t bsh,
633 u_int8_t value, size_t count);
634 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
635 bus_space_handle_t bsh,
637 u_int16_t value, size_t count);
638 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
639 bus_space_handle_t bsh,
641 u_int32_t value, size_t count);
644 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
645 bus_size_t offset, u_int8_t value, size_t count)
647 bus_space_handle_t addr = bsh + offset;
649 if (tag == X86_64_BUS_SPACE_IO)
654 *(volatile u_int8_t *)(addr) = value;
658 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
659 bus_size_t offset, u_int16_t value, size_t count)
661 bus_space_handle_t addr = bsh + offset;
663 if (tag == X86_64_BUS_SPACE_IO)
668 *(volatile u_int16_t *)(addr) = value;
672 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
673 bus_size_t offset, u_int32_t value, size_t count)
675 bus_space_handle_t addr = bsh + offset;
677 if (tag == X86_64_BUS_SPACE_IO)
682 *(volatile u_int32_t *)(addr) = value;
685 #if 0 /* Cause a link error for bus_space_set_multi_8 */
686 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
690 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
691 * by tag/handle starting at `offset'.
694 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
695 bus_space_handle_t bsh,
696 bus_size_t offset, u_int8_t value,
698 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
699 bus_space_handle_t bsh,
700 bus_size_t offset, u_int16_t value,
702 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
703 bus_space_handle_t bsh,
704 bus_size_t offset, u_int32_t value,
708 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
709 bus_size_t offset, u_int8_t value, size_t count)
711 bus_space_handle_t addr = bsh + offset;
713 if (tag == X86_64_BUS_SPACE_IO)
714 for (; count != 0; count--, addr++)
717 for (; count != 0; count--, addr++)
718 *(volatile u_int8_t *)(addr) = value;
722 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
723 bus_size_t offset, u_int16_t value, size_t count)
725 bus_space_handle_t addr = bsh + offset;
727 if (tag == X86_64_BUS_SPACE_IO)
728 for (; count != 0; count--, addr += 2)
731 for (; count != 0; count--, addr += 2)
732 *(volatile u_int16_t *)(addr) = value;
736 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
737 bus_size_t offset, u_int32_t value, size_t count)
739 bus_space_handle_t addr = bsh + offset;
741 if (tag == X86_64_BUS_SPACE_IO)
742 for (; count != 0; count--, addr += 4)
745 for (; count != 0; count--, addr += 4)
746 *(volatile u_int32_t *)(addr) = value;
749 #if 0 /* Cause a link error for bus_space_set_region_8 */
750 #define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
754 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
755 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
758 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
759 bus_space_handle_t bsh1,
761 bus_space_handle_t bsh2,
762 bus_size_t off2, size_t count);
764 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
765 bus_space_handle_t bsh1,
767 bus_space_handle_t bsh2,
768 bus_size_t off2, size_t count);
770 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
771 bus_space_handle_t bsh1,
773 bus_space_handle_t bsh2,
774 bus_size_t off2, size_t count);
777 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
778 bus_size_t off1, bus_space_handle_t bsh2,
779 bus_size_t off2, size_t count)
781 bus_space_handle_t addr1 = bsh1 + off1;
782 bus_space_handle_t addr2 = bsh2 + off2;
784 if (tag == X86_64_BUS_SPACE_IO) {
785 if (addr1 >= addr2) {
786 /* src after dest: copy forward */
787 for (; count != 0; count--, addr1++, addr2++)
788 outb(addr2, inb(addr1));
790 /* dest after src: copy backwards */
791 for (addr1 += (count - 1), addr2 += (count - 1);
792 count != 0; count--, addr1--, addr2--)
793 outb(addr2, inb(addr1));
796 if (addr1 >= addr2) {
797 /* src after dest: copy forward */
798 for (; count != 0; count--, addr1++, addr2++)
799 *(volatile u_int8_t *)(addr2) =
800 *(volatile u_int8_t *)(addr1);
802 /* dest after src: copy backwards */
803 for (addr1 += (count - 1), addr2 += (count - 1);
804 count != 0; count--, addr1--, addr2--)
805 *(volatile u_int8_t *)(addr2) =
806 *(volatile u_int8_t *)(addr1);
812 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
813 bus_size_t off1, bus_space_handle_t bsh2,
814 bus_size_t off2, size_t count)
816 bus_space_handle_t addr1 = bsh1 + off1;
817 bus_space_handle_t addr2 = bsh2 + off2;
819 if (tag == X86_64_BUS_SPACE_IO) {
820 if (addr1 >= addr2) {
821 /* src after dest: copy forward */
822 for (; count != 0; count--, addr1 += 2, addr2 += 2)
823 outw(addr2, inw(addr1));
825 /* dest after src: copy backwards */
826 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
827 count != 0; count--, addr1 -= 2, addr2 -= 2)
828 outw(addr2, inw(addr1));
831 if (addr1 >= addr2) {
832 /* src after dest: copy forward */
833 for (; count != 0; count--, addr1 += 2, addr2 += 2)
834 *(volatile u_int16_t *)(addr2) =
835 *(volatile u_int16_t *)(addr1);
837 /* dest after src: copy backwards */
838 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
839 count != 0; count--, addr1 -= 2, addr2 -= 2)
840 *(volatile u_int16_t *)(addr2) =
841 *(volatile u_int16_t *)(addr1);
847 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
848 bus_size_t off1, bus_space_handle_t bsh2,
849 bus_size_t off2, size_t count)
851 bus_space_handle_t addr1 = bsh1 + off1;
852 bus_space_handle_t addr2 = bsh2 + off2;
854 if (tag == X86_64_BUS_SPACE_IO) {
855 if (addr1 >= addr2) {
856 /* src after dest: copy forward */
857 for (; count != 0; count--, addr1 += 4, addr2 += 4)
858 outl(addr2, inl(addr1));
860 /* dest after src: copy backwards */
861 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
862 count != 0; count--, addr1 -= 4, addr2 -= 4)
863 outl(addr2, inl(addr1));
866 if (addr1 >= addr2) {
867 /* src after dest: copy forward */
868 for (; count != 0; count--, addr1 += 4, addr2 += 4)
869 *(volatile u_int32_t *)(addr2) =
870 *(volatile u_int32_t *)(addr1);
872 /* dest after src: copy backwards */
873 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
874 count != 0; count--, addr1 -= 4, addr2 -= 4)
875 *(volatile u_int32_t *)(addr2) =
876 *(volatile u_int32_t *)(addr1);
881 #if 0 /* Cause a link error for bus_space_copy_8 */
882 #define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
886 * Bus read/write barrier methods.
888 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
889 * bus_size_t offset, bus_size_t len, int flags);
892 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
893 * prevent reordering by the compiler; all Intel x86 processors currently
894 * retire operations outside the CPU in program order.
896 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
897 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
900 bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
901 bus_size_t offset __unused, bus_size_t len __unused, int flags)
903 if (flags & BUS_SPACE_BARRIER_READ)
904 __asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
906 __asm __volatile("" : : : "memory");
910 * Stream accesses are the same as normal accesses on amd64; there are no
911 * supported bus systems with an endianess different from the host one.
913 #define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o))
914 #define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o))
915 #define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o))
917 #define bus_space_read_multi_stream_1(t, h, o, a, c) \
918 bus_space_read_multi_1((t), (h), (o), (a), (c))
919 #define bus_space_read_multi_stream_2(t, h, o, a, c) \
920 bus_space_read_multi_2((t), (h), (o), (a), (c))
921 #define bus_space_read_multi_stream_4(t, h, o, a, c) \
922 bus_space_read_multi_4((t), (h), (o), (a), (c))
924 #define bus_space_write_stream_1(t, h, o, v) \
925 bus_space_write_1((t), (h), (o), (v))
926 #define bus_space_write_stream_2(t, h, o, v) \
927 bus_space_write_2((t), (h), (o), (v))
928 #define bus_space_write_stream_4(t, h, o, v) \
929 bus_space_write_4((t), (h), (o), (v))
931 #define bus_space_write_multi_stream_1(t, h, o, a, c) \
932 bus_space_write_multi_1((t), (h), (o), (a), (c))
933 #define bus_space_write_multi_stream_2(t, h, o, a, c) \
934 bus_space_write_multi_2((t), (h), (o), (a), (c))
935 #define bus_space_write_multi_stream_4(t, h, o, a, c) \
936 bus_space_write_multi_4((t), (h), (o), (a), (c))
938 #define bus_space_set_multi_stream_1(t, h, o, v, c) \
939 bus_space_set_multi_1((t), (h), (o), (v), (c))
940 #define bus_space_set_multi_stream_2(t, h, o, v, c) \
941 bus_space_set_multi_2((t), (h), (o), (v), (c))
942 #define bus_space_set_multi_stream_4(t, h, o, v, c) \
943 bus_space_set_multi_4((t), (h), (o), (v), (c))
945 #define bus_space_read_region_stream_1(t, h, o, a, c) \
946 bus_space_read_region_1((t), (h), (o), (a), (c))
947 #define bus_space_read_region_stream_2(t, h, o, a, c) \
948 bus_space_read_region_2((t), (h), (o), (a), (c))
949 #define bus_space_read_region_stream_4(t, h, o, a, c) \
950 bus_space_read_region_4((t), (h), (o), (a), (c))
952 #define bus_space_write_region_stream_1(t, h, o, a, c) \
953 bus_space_write_region_1((t), (h), (o), (a), (c))
954 #define bus_space_write_region_stream_2(t, h, o, a, c) \
955 bus_space_write_region_2((t), (h), (o), (a), (c))
956 #define bus_space_write_region_stream_4(t, h, o, a, c) \
957 bus_space_write_region_4((t), (h), (o), (a), (c))
959 #define bus_space_set_region_stream_1(t, h, o, v, c) \
960 bus_space_set_region_1((t), (h), (o), (v), (c))
961 #define bus_space_set_region_stream_2(t, h, o, v, c) \
962 bus_space_set_region_2((t), (h), (o), (v), (c))
963 #define bus_space_set_region_stream_4(t, h, o, v, c) \
964 bus_space_set_region_4((t), (h), (o), (v), (c))
966 #define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
967 bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
968 #define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
969 bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
970 #define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
971 bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
973 #endif /* _CPU_BUS_DMA_H_ */