more header changes for amd64 port; the pc64 building infrastructure
[dragonfly/port-amd64.git] / sys / cpu / amd64 / include / bus_dma.h
blobcd03113ce7b651d6dc3a8b0adc34f6be2a854131
1 /*-
2 * Copyright (c) 2005 Scott Long
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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
24 * SUCH DAMAGE.
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);
67 static __inline int
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)
73 *bshp = addr;
74 return (0);
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,
82 bus_size_t size);
84 static __inline void
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);
99 static __inline int
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;
106 return (0);
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,
123 bus_size_t size);
125 static __inline void
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,
138 bus_size_t offset);
140 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
141 bus_space_handle_t handle,
142 bus_size_t offset);
144 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
145 bus_space_handle_t handle,
146 bus_size_t offset);
148 static __inline u_int8_t
149 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
150 bus_size_t offset)
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,
160 bus_size_t offset)
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,
170 bus_size_t offset)
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 !!!
180 #endif
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,
189 size_t count);
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,
194 size_t count);
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,
199 size_t count);
201 static __inline void
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);
208 else {
209 __asm __volatile(" \n\
210 cld \n\
211 1: movb (%2),%%al \n\
212 stosb \n\
213 loop 1b" :
214 "=D" (addr), "=c" (count) :
215 "r" (bsh + offset), "0" (addr), "1" (count) :
216 "%eax", "memory");
220 static __inline void
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);
227 else {
228 __asm __volatile(" \n\
229 cld \n\
230 1: movw (%2),%%ax \n\
231 stosw \n\
232 loop 1b" :
233 "=D" (addr), "=c" (count) :
234 "r" (bsh + offset), "0" (addr), "1" (count) :
235 "%eax", "memory");
239 static __inline void
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);
246 else {
247 __asm __volatile(" \n\
248 cld \n\
249 1: movl (%2),%%eax \n\
250 stosl \n\
251 loop 1b" :
252 "=D" (addr), "=c" (count) :
253 "r" (bsh + offset), "0" (addr), "1" (count) :
254 "%eax", "memory");
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 !!!
260 #endif
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
265 * buffer provided.
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,
270 size_t count);
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,
275 size_t count);
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,
280 size_t count);
283 static __inline void
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\
291 cld \n\
292 1: inb %w2,%%al \n\
293 stosb \n\
294 incl %2 \n\
295 loop 1b" :
296 "=D" (addr), "=c" (count), "=d" (_port_) :
297 "0" (addr), "1" (count), "2" (_port_) :
298 "%eax", "memory", "cc");
299 } else {
300 bus_space_handle_t _port_ = bsh + offset;
301 __asm __volatile(" \n\
302 cld \n\
303 repne \n\
304 movsb" :
305 "=D" (addr), "=c" (count), "=S" (_port_) :
306 "0" (addr), "1" (count), "2" (_port_) :
307 "memory", "cc");
311 static __inline void
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\
319 cld \n\
320 1: inw %w2,%%ax \n\
321 stosw \n\
322 addl $2,%2 \n\
323 loop 1b" :
324 "=D" (addr), "=c" (count), "=d" (_port_) :
325 "0" (addr), "1" (count), "2" (_port_) :
326 "%eax", "memory", "cc");
327 } else {
328 bus_space_handle_t _port_ = bsh + offset;
329 __asm __volatile(" \n\
330 cld \n\
331 repne \n\
332 movsw" :
333 "=D" (addr), "=c" (count), "=S" (_port_) :
334 "0" (addr), "1" (count), "2" (_port_) :
335 "memory", "cc");
339 static __inline void
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\
347 cld \n\
348 1: inl %w2,%%eax \n\
349 stosl \n\
350 addl $4,%2 \n\
351 loop 1b" :
352 "=D" (addr), "=c" (count), "=d" (_port_) :
353 "0" (addr), "1" (count), "2" (_port_) :
354 "%eax", "memory", "cc");
355 } else {
356 bus_space_handle_t _port_ = bsh + offset;
357 __asm __volatile(" \n\
358 cld \n\
359 repne \n\
360 movsl" :
361 "=D" (addr), "=c" (count), "=S" (_port_) :
362 "0" (addr), "1" (count), "2" (_port_) :
363 "memory", "cc");
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 !!!
369 #endif
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);
388 static __inline void
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);
395 else
396 *(volatile u_int8_t *)(bsh + offset) = value;
399 static __inline void
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);
406 else
407 *(volatile u_int16_t *)(bsh + offset) = value;
410 static __inline void
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);
417 else
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 !!!
423 #endif
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,
432 bus_size_t offset,
433 const u_int8_t *addr,
434 size_t count);
435 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
436 bus_space_handle_t bsh,
437 bus_size_t offset,
438 const u_int16_t *addr,
439 size_t count);
441 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
442 bus_space_handle_t bsh,
443 bus_size_t offset,
444 const u_int32_t *addr,
445 size_t count);
447 static __inline void
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);
454 else {
455 __asm __volatile(" \n\
456 cld \n\
457 1: lodsb \n\
458 movb %%al,(%2) \n\
459 loop 1b" :
460 "=S" (addr), "=c" (count) :
461 "r" (bsh + offset), "0" (addr), "1" (count) :
462 "%eax", "memory", "cc");
466 static __inline void
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);
473 else {
474 __asm __volatile(" \n\
475 cld \n\
476 1: lodsw \n\
477 movw %%ax,(%2) \n\
478 loop 1b" :
479 "=S" (addr), "=c" (count) :
480 "r" (bsh + offset), "0" (addr), "1" (count) :
481 "%eax", "memory", "cc");
485 static __inline void
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);
492 else {
493 __asm __volatile(" \n\
494 cld \n\
495 1: lodsl \n\
496 movl %%eax,(%2) \n\
497 loop 1b" :
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 !!!
507 #endif
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,
516 bus_size_t offset,
517 const u_int8_t *addr,
518 size_t count);
519 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
520 bus_space_handle_t bsh,
521 bus_size_t offset,
522 const u_int16_t *addr,
523 size_t count);
524 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
525 bus_space_handle_t bsh,
526 bus_size_t offset,
527 const u_int32_t *addr,
528 size_t count);
530 static __inline void
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\
538 cld \n\
539 1: lodsb \n\
540 outb %%al,%w0 \n\
541 incl %0 \n\
542 loop 1b" :
543 "=d" (_port_), "=S" (addr), "=c" (count) :
544 "0" (_port_), "1" (addr), "2" (count) :
545 "%eax", "memory", "cc");
546 } else {
547 bus_space_handle_t _port_ = bsh + offset;
548 __asm __volatile(" \n\
549 cld \n\
550 repne \n\
551 movsb" :
552 "=D" (_port_), "=S" (addr), "=c" (count) :
553 "0" (_port_), "1" (addr), "2" (count) :
554 "memory", "cc");
558 static __inline void
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\
566 cld \n\
567 1: lodsw \n\
568 outw %%ax,%w0 \n\
569 addl $2,%0 \n\
570 loop 1b" :
571 "=d" (_port_), "=S" (addr), "=c" (count) :
572 "0" (_port_), "1" (addr), "2" (count) :
573 "%eax", "memory", "cc");
574 } else {
575 bus_space_handle_t _port_ = bsh + offset;
576 __asm __volatile(" \n\
577 cld \n\
578 repne \n\
579 movsw" :
580 "=D" (_port_), "=S" (addr), "=c" (count) :
581 "0" (_port_), "1" (addr), "2" (count) :
582 "memory", "cc");
586 static __inline void
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\
594 cld \n\
595 1: lodsl \n\
596 outl %%eax,%w0 \n\
597 addl $4,%0 \n\
598 loop 1b" :
599 "=d" (_port_), "=S" (addr), "=c" (count) :
600 "0" (_port_), "1" (addr), "2" (count) :
601 "%eax", "memory", "cc");
602 } else {
603 bus_space_handle_t _port_ = bsh + offset;
604 __asm __volatile(" \n\
605 cld \n\
606 repne \n\
607 movsl" :
608 "=D" (_port_), "=S" (addr), "=c" (count) :
609 "0" (_port_), "1" (addr), "2" (count) :
610 "memory", "cc");
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 !!!
617 #endif
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,
626 bus_size_t offset,
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,
630 bus_size_t offset,
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,
634 bus_size_t offset,
635 u_int32_t value, size_t count);
637 static __inline void
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)
644 while (count--)
645 outb(addr, value);
646 else
647 while (count--)
648 *(volatile u_int8_t *)(addr) = value;
651 static __inline void
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)
658 while (count--)
659 outw(addr, value);
660 else
661 while (count--)
662 *(volatile u_int16_t *)(addr) = value;
665 static __inline void
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)
672 while (count--)
673 outl(addr, value);
674 else
675 while (count--)
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 !!!
681 #endif
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,
691 size_t count);
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,
695 size_t count);
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,
699 size_t count);
701 static __inline void
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++)
709 outb(addr, value);
710 else
711 for (; count != 0; count--, addr++)
712 *(volatile u_int8_t *)(addr) = value;
715 static __inline void
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)
723 outw(addr, value);
724 else
725 for (; count != 0; count--, addr += 2)
726 *(volatile u_int16_t *)(addr) = value;
729 static __inline void
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)
737 outl(addr, value);
738 else
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 !!!
745 #endif
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,
754 bus_size_t off1,
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,
760 bus_size_t off1,
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,
766 bus_size_t off1,
767 bus_space_handle_t bsh2,
768 bus_size_t off2, size_t count);
770 static __inline void
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));
783 } else {
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));
789 } else {
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);
795 } else {
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);
805 static __inline void
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));
818 } else {
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));
824 } else {
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);
830 } else {
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);
840 static __inline void
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));
853 } else {
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));
859 } else {
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);
865 } else {
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 !!!
877 #endif
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 */
893 static __inline void
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");
899 else
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_ */