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
;
110 * Allocate a region of memory that is accessible to devices in bus space.
113 int bus_space_alloc(bus_space_tag_t t
, bus_addr_t rstart
,
114 bus_addr_t rend
, bus_size_t size
, bus_size_t align
,
115 bus_size_t boundary
, int flags
, bus_addr_t
*addrp
,
116 bus_space_handle_t
*bshp
);
119 * Free a region of bus space accessible memory.
122 static __inline
void bus_space_free(bus_space_tag_t t
, bus_space_handle_t bsh
,
126 bus_space_free(bus_space_tag_t t __unused
, bus_space_handle_t bsh __unused
,
127 bus_size_t size __unused
)
133 * Read a 1, 2, 4, or 8 byte quantity from bus space
134 * described by tag/handle/offset.
136 static __inline u_int8_t
bus_space_read_1(bus_space_tag_t tag
,
137 bus_space_handle_t handle
,
140 static __inline u_int16_t
bus_space_read_2(bus_space_tag_t tag
,
141 bus_space_handle_t handle
,
144 static __inline u_int32_t
bus_space_read_4(bus_space_tag_t tag
,
145 bus_space_handle_t handle
,
148 static __inline u_int8_t
149 bus_space_read_1(bus_space_tag_t tag
, bus_space_handle_t handle
,
153 if (tag
== AMD64_BUS_SPACE_IO
)
154 return (inb(handle
+ offset
));
155 return (*(volatile u_int8_t
*)(handle
+ offset
));
158 static __inline u_int16_t
159 bus_space_read_2(bus_space_tag_t tag
, bus_space_handle_t handle
,
163 if (tag
== AMD64_BUS_SPACE_IO
)
164 return (inw(handle
+ offset
));
165 return (*(volatile u_int16_t
*)(handle
+ offset
));
168 static __inline u_int32_t
169 bus_space_read_4(bus_space_tag_t tag
, bus_space_handle_t handle
,
173 if (tag
== AMD64_BUS_SPACE_IO
)
174 return (inl(handle
+ offset
));
175 return (*(volatile u_int32_t
*)(handle
+ offset
));
178 #if 0 /* Cause a link error for bus_space_read_8 */
179 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
183 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
184 * described by tag/handle/offset and copy into buffer provided.
186 static __inline
void bus_space_read_multi_1(bus_space_tag_t tag
,
187 bus_space_handle_t bsh
,
188 bus_size_t offset
, u_int8_t
*addr
,
191 static __inline
void bus_space_read_multi_2(bus_space_tag_t tag
,
192 bus_space_handle_t bsh
,
193 bus_size_t offset
, u_int16_t
*addr
,
196 static __inline
void bus_space_read_multi_4(bus_space_tag_t tag
,
197 bus_space_handle_t bsh
,
198 bus_size_t offset
, u_int32_t
*addr
,
202 bus_space_read_multi_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
203 bus_size_t offset
, u_int8_t
*addr
, size_t count
)
206 if (tag
== AMD64_BUS_SPACE_IO
)
207 insb(bsh
+ offset
, addr
, count
);
209 __asm
__volatile(" \n\
211 1: movb (%2),%%al \n\
214 "=D" (addr
), "=c" (count
) :
215 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
221 bus_space_read_multi_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
222 bus_size_t offset
, u_int16_t
*addr
, size_t count
)
225 if (tag
== AMD64_BUS_SPACE_IO
)
226 insw(bsh
+ offset
, addr
, count
);
228 __asm
__volatile(" \n\
230 1: movw (%2),%%ax \n\
233 "=D" (addr
), "=c" (count
) :
234 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
240 bus_space_read_multi_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
241 bus_size_t offset
, u_int32_t
*addr
, size_t count
)
244 if (tag
== AMD64_BUS_SPACE_IO
)
245 insl(bsh
+ offset
, addr
, count
);
247 __asm
__volatile(" \n\
249 1: movl (%2),%%eax \n\
252 "=D" (addr
), "=c" (count
) :
253 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
258 #if 0 /* Cause a link error for bus_space_read_multi_8 */
259 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
263 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
264 * described by tag/handle and starting at `offset' and copy into
267 static __inline
void bus_space_read_region_1(bus_space_tag_t tag
,
268 bus_space_handle_t bsh
,
269 bus_size_t offset
, u_int8_t
*addr
,
272 static __inline
void bus_space_read_region_2(bus_space_tag_t tag
,
273 bus_space_handle_t bsh
,
274 bus_size_t offset
, u_int16_t
*addr
,
277 static __inline
void bus_space_read_region_4(bus_space_tag_t tag
,
278 bus_space_handle_t bsh
,
279 bus_size_t offset
, u_int32_t
*addr
,
284 bus_space_read_region_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
285 bus_size_t offset
, u_int8_t
*addr
, size_t count
)
288 if (tag
== AMD64_BUS_SPACE_IO
) {
289 int _port_
= bsh
+ offset
;
290 __asm
__volatile(" \n\
296 "=D" (addr
), "=c" (count
), "=d" (_port_
) :
297 "0" (addr
), "1" (count
), "2" (_port_
) :
298 "%eax", "memory", "cc");
300 bus_space_handle_t _port_
= bsh
+ offset
;
301 __asm
__volatile(" \n\
305 "=D" (addr
), "=c" (count
), "=S" (_port_
) :
306 "0" (addr
), "1" (count
), "2" (_port_
) :
312 bus_space_read_region_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
313 bus_size_t offset
, u_int16_t
*addr
, size_t count
)
316 if (tag
== AMD64_BUS_SPACE_IO
) {
317 int _port_
= bsh
+ offset
;
318 __asm
__volatile(" \n\
324 "=D" (addr
), "=c" (count
), "=d" (_port_
) :
325 "0" (addr
), "1" (count
), "2" (_port_
) :
326 "%eax", "memory", "cc");
328 bus_space_handle_t _port_
= bsh
+ offset
;
329 __asm
__volatile(" \n\
333 "=D" (addr
), "=c" (count
), "=S" (_port_
) :
334 "0" (addr
), "1" (count
), "2" (_port_
) :
340 bus_space_read_region_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
341 bus_size_t offset
, u_int32_t
*addr
, size_t count
)
344 if (tag
== AMD64_BUS_SPACE_IO
) {
345 int _port_
= bsh
+ offset
;
346 __asm
__volatile(" \n\
352 "=D" (addr
), "=c" (count
), "=d" (_port_
) :
353 "0" (addr
), "1" (count
), "2" (_port_
) :
354 "%eax", "memory", "cc");
356 bus_space_handle_t _port_
= bsh
+ offset
;
357 __asm
__volatile(" \n\
361 "=D" (addr
), "=c" (count
), "=S" (_port_
) :
362 "0" (addr
), "1" (count
), "2" (_port_
) :
367 #if 0 /* Cause a link error for bus_space_read_region_8 */
368 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
372 * Write the 1, 2, 4, or 8 byte value `value' to bus space
373 * described by tag/handle/offset.
376 static __inline
void bus_space_write_1(bus_space_tag_t tag
,
377 bus_space_handle_t bsh
,
378 bus_size_t offset
, u_int8_t value
);
380 static __inline
void bus_space_write_2(bus_space_tag_t tag
,
381 bus_space_handle_t bsh
,
382 bus_size_t offset
, u_int16_t value
);
384 static __inline
void bus_space_write_4(bus_space_tag_t tag
,
385 bus_space_handle_t bsh
,
386 bus_size_t offset
, u_int32_t value
);
389 bus_space_write_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
390 bus_size_t offset
, u_int8_t value
)
393 if (tag
== AMD64_BUS_SPACE_IO
)
394 outb(bsh
+ offset
, value
);
396 *(volatile u_int8_t
*)(bsh
+ offset
) = value
;
400 bus_space_write_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
401 bus_size_t offset
, u_int16_t value
)
404 if (tag
== AMD64_BUS_SPACE_IO
)
405 outw(bsh
+ offset
, value
);
407 *(volatile u_int16_t
*)(bsh
+ offset
) = value
;
411 bus_space_write_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
412 bus_size_t offset
, u_int32_t value
)
415 if (tag
== AMD64_BUS_SPACE_IO
)
416 outl(bsh
+ offset
, value
);
418 *(volatile u_int32_t
*)(bsh
+ offset
) = value
;
421 #if 0 /* Cause a link error for bus_space_write_8 */
422 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
426 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
427 * provided to bus space described by tag/handle/offset.
430 static __inline
void bus_space_write_multi_1(bus_space_tag_t tag
,
431 bus_space_handle_t bsh
,
433 const u_int8_t
*addr
,
435 static __inline
void bus_space_write_multi_2(bus_space_tag_t tag
,
436 bus_space_handle_t bsh
,
438 const u_int16_t
*addr
,
441 static __inline
void bus_space_write_multi_4(bus_space_tag_t tag
,
442 bus_space_handle_t bsh
,
444 const u_int32_t
*addr
,
448 bus_space_write_multi_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
449 bus_size_t offset
, const u_int8_t
*addr
, size_t count
)
452 if (tag
== AMD64_BUS_SPACE_IO
)
453 outsb(bsh
+ offset
, addr
, count
);
455 __asm
__volatile(" \n\
460 "=S" (addr
), "=c" (count
) :
461 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
462 "%eax", "memory", "cc");
467 bus_space_write_multi_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
468 bus_size_t offset
, const u_int16_t
*addr
, size_t count
)
471 if (tag
== AMD64_BUS_SPACE_IO
)
472 outsw(bsh
+ offset
, addr
, count
);
474 __asm
__volatile(" \n\
479 "=S" (addr
), "=c" (count
) :
480 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
481 "%eax", "memory", "cc");
486 bus_space_write_multi_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
487 bus_size_t offset
, const u_int32_t
*addr
, size_t count
)
490 if (tag
== AMD64_BUS_SPACE_IO
)
491 outsl(bsh
+ offset
, addr
, count
);
493 __asm
__volatile(" \n\
498 "=S" (addr
), "=c" (count
) :
499 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
500 "%eax", "memory", "cc");
504 #if 0 /* Cause a link error for bus_space_write_multi_8 */
505 #define bus_space_write_multi_8(t, h, o, a, c) \
506 !!! bus_space_write_multi_8 unimplemented !!!
510 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
511 * to bus space described by tag/handle starting at `offset'.
514 static __inline
void bus_space_write_region_1(bus_space_tag_t tag
,
515 bus_space_handle_t bsh
,
517 const u_int8_t
*addr
,
519 static __inline
void bus_space_write_region_2(bus_space_tag_t tag
,
520 bus_space_handle_t bsh
,
522 const u_int16_t
*addr
,
524 static __inline
void bus_space_write_region_4(bus_space_tag_t tag
,
525 bus_space_handle_t bsh
,
527 const u_int32_t
*addr
,
531 bus_space_write_region_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
532 bus_size_t offset
, const u_int8_t
*addr
, size_t count
)
535 if (tag
== AMD64_BUS_SPACE_IO
) {
536 int _port_
= bsh
+ offset
;
537 __asm
__volatile(" \n\
543 "=d" (_port_
), "=S" (addr
), "=c" (count
) :
544 "0" (_port_
), "1" (addr
), "2" (count
) :
545 "%eax", "memory", "cc");
547 bus_space_handle_t _port_
= bsh
+ offset
;
548 __asm
__volatile(" \n\
552 "=D" (_port_
), "=S" (addr
), "=c" (count
) :
553 "0" (_port_
), "1" (addr
), "2" (count
) :
559 bus_space_write_region_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
560 bus_size_t offset
, const u_int16_t
*addr
, size_t count
)
563 if (tag
== AMD64_BUS_SPACE_IO
) {
564 int _port_
= bsh
+ offset
;
565 __asm
__volatile(" \n\
571 "=d" (_port_
), "=S" (addr
), "=c" (count
) :
572 "0" (_port_
), "1" (addr
), "2" (count
) :
573 "%eax", "memory", "cc");
575 bus_space_handle_t _port_
= bsh
+ offset
;
576 __asm
__volatile(" \n\
580 "=D" (_port_
), "=S" (addr
), "=c" (count
) :
581 "0" (_port_
), "1" (addr
), "2" (count
) :
587 bus_space_write_region_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
588 bus_size_t offset
, const u_int32_t
*addr
, size_t count
)
591 if (tag
== AMD64_BUS_SPACE_IO
) {
592 int _port_
= bsh
+ offset
;
593 __asm
__volatile(" \n\
599 "=d" (_port_
), "=S" (addr
), "=c" (count
) :
600 "0" (_port_
), "1" (addr
), "2" (count
) :
601 "%eax", "memory", "cc");
603 bus_space_handle_t _port_
= bsh
+ offset
;
604 __asm
__volatile(" \n\
608 "=D" (_port_
), "=S" (addr
), "=c" (count
) :
609 "0" (_port_
), "1" (addr
), "2" (count
) :
614 #if 0 /* Cause a link error for bus_space_write_region_8 */
615 #define bus_space_write_region_8 \
616 !!! bus_space_write_region_8 unimplemented !!!
620 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
621 * by tag/handle/offset `count' times.
624 static __inline
void bus_space_set_multi_1(bus_space_tag_t tag
,
625 bus_space_handle_t bsh
,
627 u_int8_t value
, size_t count
);
628 static __inline
void bus_space_set_multi_2(bus_space_tag_t tag
,
629 bus_space_handle_t bsh
,
631 u_int16_t value
, size_t count
);
632 static __inline
void bus_space_set_multi_4(bus_space_tag_t tag
,
633 bus_space_handle_t bsh
,
635 u_int32_t value
, size_t count
);
638 bus_space_set_multi_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
639 bus_size_t offset
, u_int8_t value
, size_t count
)
641 bus_space_handle_t addr
= bsh
+ offset
;
643 if (tag
== AMD64_BUS_SPACE_IO
)
648 *(volatile u_int8_t
*)(addr
) = value
;
652 bus_space_set_multi_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
653 bus_size_t offset
, u_int16_t value
, size_t count
)
655 bus_space_handle_t addr
= bsh
+ offset
;
657 if (tag
== AMD64_BUS_SPACE_IO
)
662 *(volatile u_int16_t
*)(addr
) = value
;
666 bus_space_set_multi_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
667 bus_size_t offset
, u_int32_t value
, size_t count
)
669 bus_space_handle_t addr
= bsh
+ offset
;
671 if (tag
== AMD64_BUS_SPACE_IO
)
676 *(volatile u_int32_t
*)(addr
) = value
;
679 #if 0 /* Cause a link error for bus_space_set_multi_8 */
680 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
684 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
685 * by tag/handle starting at `offset'.
688 static __inline
void bus_space_set_region_1(bus_space_tag_t tag
,
689 bus_space_handle_t bsh
,
690 bus_size_t offset
, u_int8_t value
,
692 static __inline
void bus_space_set_region_2(bus_space_tag_t tag
,
693 bus_space_handle_t bsh
,
694 bus_size_t offset
, u_int16_t value
,
696 static __inline
void bus_space_set_region_4(bus_space_tag_t tag
,
697 bus_space_handle_t bsh
,
698 bus_size_t offset
, u_int32_t value
,
702 bus_space_set_region_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
703 bus_size_t offset
, u_int8_t value
, size_t count
)
705 bus_space_handle_t addr
= bsh
+ offset
;
707 if (tag
== AMD64_BUS_SPACE_IO
)
708 for (; count
!= 0; count
--, addr
++)
711 for (; count
!= 0; count
--, addr
++)
712 *(volatile u_int8_t
*)(addr
) = value
;
716 bus_space_set_region_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
717 bus_size_t offset
, u_int16_t value
, size_t count
)
719 bus_space_handle_t addr
= bsh
+ offset
;
721 if (tag
== AMD64_BUS_SPACE_IO
)
722 for (; count
!= 0; count
--, addr
+= 2)
725 for (; count
!= 0; count
--, addr
+= 2)
726 *(volatile u_int16_t
*)(addr
) = value
;
730 bus_space_set_region_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
731 bus_size_t offset
, u_int32_t value
, size_t count
)
733 bus_space_handle_t addr
= bsh
+ offset
;
735 if (tag
== AMD64_BUS_SPACE_IO
)
736 for (; count
!= 0; count
--, addr
+= 4)
739 for (; count
!= 0; count
--, addr
+= 4)
740 *(volatile u_int32_t
*)(addr
) = value
;
743 #if 0 /* Cause a link error for bus_space_set_region_8 */
744 #define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
748 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
749 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
752 static __inline
void bus_space_copy_region_1(bus_space_tag_t tag
,
753 bus_space_handle_t bsh1
,
755 bus_space_handle_t bsh2
,
756 bus_size_t off2
, size_t count
);
758 static __inline
void bus_space_copy_region_2(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_4(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
);
771 bus_space_copy_region_1(bus_space_tag_t tag
, bus_space_handle_t bsh1
,
772 bus_size_t off1
, bus_space_handle_t bsh2
,
773 bus_size_t off2
, size_t count
)
775 bus_space_handle_t addr1
= bsh1
+ off1
;
776 bus_space_handle_t addr2
= bsh2
+ off2
;
778 if (tag
== AMD64_BUS_SPACE_IO
) {
779 if (addr1
>= addr2
) {
780 /* src after dest: copy forward */
781 for (; count
!= 0; count
--, addr1
++, addr2
++)
782 outb(addr2
, inb(addr1
));
784 /* dest after src: copy backwards */
785 for (addr1
+= (count
- 1), addr2
+= (count
- 1);
786 count
!= 0; count
--, addr1
--, addr2
--)
787 outb(addr2
, inb(addr1
));
790 if (addr1
>= addr2
) {
791 /* src after dest: copy forward */
792 for (; count
!= 0; count
--, addr1
++, addr2
++)
793 *(volatile u_int8_t
*)(addr2
) =
794 *(volatile u_int8_t
*)(addr1
);
796 /* dest after src: copy backwards */
797 for (addr1
+= (count
- 1), addr2
+= (count
- 1);
798 count
!= 0; count
--, addr1
--, addr2
--)
799 *(volatile u_int8_t
*)(addr2
) =
800 *(volatile u_int8_t
*)(addr1
);
806 bus_space_copy_region_2(bus_space_tag_t tag
, bus_space_handle_t bsh1
,
807 bus_size_t off1
, bus_space_handle_t bsh2
,
808 bus_size_t off2
, size_t count
)
810 bus_space_handle_t addr1
= bsh1
+ off1
;
811 bus_space_handle_t addr2
= bsh2
+ off2
;
813 if (tag
== AMD64_BUS_SPACE_IO
) {
814 if (addr1
>= addr2
) {
815 /* src after dest: copy forward */
816 for (; count
!= 0; count
--, addr1
+= 2, addr2
+= 2)
817 outw(addr2
, inw(addr1
));
819 /* dest after src: copy backwards */
820 for (addr1
+= 2 * (count
- 1), addr2
+= 2 * (count
- 1);
821 count
!= 0; count
--, addr1
-= 2, addr2
-= 2)
822 outw(addr2
, inw(addr1
));
825 if (addr1
>= addr2
) {
826 /* src after dest: copy forward */
827 for (; count
!= 0; count
--, addr1
+= 2, addr2
+= 2)
828 *(volatile u_int16_t
*)(addr2
) =
829 *(volatile u_int16_t
*)(addr1
);
831 /* dest after src: copy backwards */
832 for (addr1
+= 2 * (count
- 1), addr2
+= 2 * (count
- 1);
833 count
!= 0; count
--, addr1
-= 2, addr2
-= 2)
834 *(volatile u_int16_t
*)(addr2
) =
835 *(volatile u_int16_t
*)(addr1
);
841 bus_space_copy_region_4(bus_space_tag_t tag
, bus_space_handle_t bsh1
,
842 bus_size_t off1
, bus_space_handle_t bsh2
,
843 bus_size_t off2
, size_t count
)
845 bus_space_handle_t addr1
= bsh1
+ off1
;
846 bus_space_handle_t addr2
= bsh2
+ off2
;
848 if (tag
== AMD64_BUS_SPACE_IO
) {
849 if (addr1
>= addr2
) {
850 /* src after dest: copy forward */
851 for (; count
!= 0; count
--, addr1
+= 4, addr2
+= 4)
852 outl(addr2
, inl(addr1
));
854 /* dest after src: copy backwards */
855 for (addr1
+= 4 * (count
- 1), addr2
+= 4 * (count
- 1);
856 count
!= 0; count
--, addr1
-= 4, addr2
-= 4)
857 outl(addr2
, inl(addr1
));
860 if (addr1
>= addr2
) {
861 /* src after dest: copy forward */
862 for (; count
!= 0; count
--, addr1
+= 4, addr2
+= 4)
863 *(volatile u_int32_t
*)(addr2
) =
864 *(volatile u_int32_t
*)(addr1
);
866 /* dest after src: copy backwards */
867 for (addr1
+= 4 * (count
- 1), addr2
+= 4 * (count
- 1);
868 count
!= 0; count
--, addr1
-= 4, addr2
-= 4)
869 *(volatile u_int32_t
*)(addr2
) =
870 *(volatile u_int32_t
*)(addr1
);
875 #if 0 /* Cause a link error for bus_space_copy_8 */
876 #define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
880 * Bus read/write barrier methods.
882 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
883 * bus_size_t offset, bus_size_t len, int flags);
886 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
887 * prevent reordering by the compiler; all Intel x86 processors currently
888 * retire operations outside the CPU in program order.
890 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
891 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
894 bus_space_barrier(bus_space_tag_t tag __unused
, bus_space_handle_t bsh __unused
,
895 bus_size_t offset __unused
, bus_size_t len __unused
, int flags
)
897 if (flags
& BUS_SPACE_BARRIER_READ
)
898 __asm
__volatile("lock; addl $0,0(%%rsp)" : : : "memory");
900 __asm
__volatile("" : : : "memory");
904 * Stream accesses are the same as normal accesses on amd64; there are no
905 * supported bus systems with an endianess different from the host one.
907 #define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o))
908 #define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o))
909 #define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o))
911 #define bus_space_read_multi_stream_1(t, h, o, a, c) \
912 bus_space_read_multi_1((t), (h), (o), (a), (c))
913 #define bus_space_read_multi_stream_2(t, h, o, a, c) \
914 bus_space_read_multi_2((t), (h), (o), (a), (c))
915 #define bus_space_read_multi_stream_4(t, h, o, a, c) \
916 bus_space_read_multi_4((t), (h), (o), (a), (c))
918 #define bus_space_write_stream_1(t, h, o, v) \
919 bus_space_write_1((t), (h), (o), (v))
920 #define bus_space_write_stream_2(t, h, o, v) \
921 bus_space_write_2((t), (h), (o), (v))
922 #define bus_space_write_stream_4(t, h, o, v) \
923 bus_space_write_4((t), (h), (o), (v))
925 #define bus_space_write_multi_stream_1(t, h, o, a, c) \
926 bus_space_write_multi_1((t), (h), (o), (a), (c))
927 #define bus_space_write_multi_stream_2(t, h, o, a, c) \
928 bus_space_write_multi_2((t), (h), (o), (a), (c))
929 #define bus_space_write_multi_stream_4(t, h, o, a, c) \
930 bus_space_write_multi_4((t), (h), (o), (a), (c))
932 #define bus_space_set_multi_stream_1(t, h, o, v, c) \
933 bus_space_set_multi_1((t), (h), (o), (v), (c))
934 #define bus_space_set_multi_stream_2(t, h, o, v, c) \
935 bus_space_set_multi_2((t), (h), (o), (v), (c))
936 #define bus_space_set_multi_stream_4(t, h, o, v, c) \
937 bus_space_set_multi_4((t), (h), (o), (v), (c))
939 #define bus_space_read_region_stream_1(t, h, o, a, c) \
940 bus_space_read_region_1((t), (h), (o), (a), (c))
941 #define bus_space_read_region_stream_2(t, h, o, a, c) \
942 bus_space_read_region_2((t), (h), (o), (a), (c))
943 #define bus_space_read_region_stream_4(t, h, o, a, c) \
944 bus_space_read_region_4((t), (h), (o), (a), (c))
946 #define bus_space_write_region_stream_1(t, h, o, a, c) \
947 bus_space_write_region_1((t), (h), (o), (a), (c))
948 #define bus_space_write_region_stream_2(t, h, o, a, c) \
949 bus_space_write_region_2((t), (h), (o), (a), (c))
950 #define bus_space_write_region_stream_4(t, h, o, a, c) \
951 bus_space_write_region_4((t), (h), (o), (a), (c))
953 #define bus_space_set_region_stream_1(t, h, o, v, c) \
954 bus_space_set_region_1((t), (h), (o), (v), (c))
955 #define bus_space_set_region_stream_2(t, h, o, v, c) \
956 bus_space_set_region_2((t), (h), (o), (v), (c))
957 #define bus_space_set_region_stream_4(t, h, o, v, c) \
958 bus_space_set_region_4((t), (h), (o), (v), (c))
960 #define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
961 bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
962 #define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
963 bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
964 #define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
965 bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
967 #endif /* _CPU_BUS_DMA_H_ */