2 * Copyright (c) KATO Takenori, 1999.
4 * All rights reserved. Unpublished rights reserved under the copyright
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer as
13 * the first lines of this file unmodified.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 /* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */
37 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
38 * All rights reserved.
40 * This code is derived from software contributed to The NetBSD Foundation
41 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
42 * NASA Ames Research Center.
44 * Redistribution and use in source and binary forms, with or without
45 * modification, are permitted provided that the following conditions
47 * 1. Redistributions of source code must retain the above copyright
48 * notice, this list of conditions and the following disclaimer.
49 * 2. Redistributions in binary form must reproduce the above copyright
50 * notice, this list of conditions and the following disclaimer in the
51 * documentation and/or other materials provided with the distribution.
52 * 3. All advertising materials mentioning features or use of this software
53 * must display the following acknowledgement:
54 * This product includes software developed by the NetBSD
55 * Foundation, Inc. and its contributors.
56 * 4. Neither the name of The NetBSD Foundation nor the names of its
57 * contributors may be used to endorse or promote products derived
58 * from this software without specific prior written permission.
60 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
61 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
62 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
64 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
65 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
66 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
67 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
68 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
69 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
70 * POSSIBILITY OF SUCH DAMAGE.
74 * Copyright (c) 1996 Charles M. Hannum. All rights reserved.
75 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
77 * Redistribution and use in source and binary forms, with or without
78 * modification, are permitted provided that the following conditions
80 * 1. Redistributions of source code must retain the above copyright
81 * notice, this list of conditions and the following disclaimer.
82 * 2. Redistributions in binary form must reproduce the above copyright
83 * notice, this list of conditions and the following disclaimer in the
84 * documentation and/or other materials provided with the distribution.
85 * 3. All advertising materials mentioning features or use of this software
86 * must display the following acknowledgement:
87 * This product includes software developed by Christopher G. Demetriou
88 * for the NetBSD Project.
89 * 4. The name of the author may not be used to endorse or promote products
90 * derived from this software without specific prior written permission
92 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
93 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
94 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
95 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
96 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
97 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
98 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
99 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
100 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
101 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
107 #include <machine/_bus.h>
108 #include <machine/cpufunc.h>
110 #ifndef __GNUCLIKE_ASM
112 # error "no assembler code for your compiler"
117 * Values for the x86 bus space tag, not to be used directly by MI code.
119 #define X86_BUS_SPACE_IO 0 /* space is i/o space */
120 #define X86_BUS_SPACE_MEM 1 /* space is mem space */
122 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
123 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
124 #define BUS_SPACE_MAXSIZE 0xFFFFFFFF
125 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
126 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
127 #if defined(__amd64__) || defined(PAE)
128 #define BUS_SPACE_MAXADDR 0xFFFFFFFFFFFFFFFFULL
130 #define BUS_SPACE_MAXADDR 0xFFFFFFFF
133 #define BUS_SPACE_UNRESTRICTED (~0)
136 * Map a region of device bus space into CPU virtual address space.
139 static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
140 bus_size_t size, int flags,
141 bus_space_handle_t *bshp);
144 bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
145 bus_size_t size __unused, int flags __unused,
146 bus_space_handle_t *bshp)
154 * Unmap a region of device bus space.
157 static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
161 bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
162 bus_size_t size __unused)
167 * Get a new handle for a subregion of an already-mapped area of bus space.
170 static __inline int bus_space_subregion(bus_space_tag_t t,
171 bus_space_handle_t bsh,
172 bus_size_t offset, bus_size_t size,
173 bus_space_handle_t *nbshp);
176 bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
177 bus_size_t offset, bus_size_t size __unused,
178 bus_space_handle_t *nbshp)
181 *nbshp = bsh + offset;
186 * Allocate a region of memory that is accessible to devices in bus space.
189 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
190 bus_addr_t rend, bus_size_t size, bus_size_t align,
191 bus_size_t boundary, int flags, bus_addr_t *addrp,
192 bus_space_handle_t *bshp);
195 * Free a region of bus space accessible memory.
198 static __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
202 bus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
203 bus_size_t size __unused)
209 * Read a 1, 2, 4, or 8 byte quantity from bus space
210 * described by tag/handle/offset.
212 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
213 bus_space_handle_t handle,
216 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
217 bus_space_handle_t handle,
220 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
221 bus_space_handle_t handle,
224 static __inline u_int8_t
225 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
229 if (tag == X86_BUS_SPACE_IO)
230 return (inb(handle + offset));
231 return (*(volatile u_int8_t *)(handle + offset));
234 static __inline u_int16_t
235 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
239 if (tag == X86_BUS_SPACE_IO)
240 return (inw(handle + offset));
241 return (*(volatile u_int16_t *)(handle + offset));
244 static __inline u_int32_t
245 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
249 if (tag == X86_BUS_SPACE_IO)
250 return (inl(handle + offset));
251 return (*(volatile u_int32_t *)(handle + offset));
254 #if 0 /* Cause a link error for bus_space_read_8 */
255 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
259 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
260 * described by tag/handle/offset and copy into buffer provided.
262 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
263 bus_space_handle_t bsh,
264 bus_size_t offset, u_int8_t *addr,
267 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
268 bus_space_handle_t bsh,
269 bus_size_t offset, u_int16_t *addr,
272 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
273 bus_space_handle_t bsh,
274 bus_size_t offset, u_int32_t *addr,
278 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
279 bus_size_t offset, u_int8_t *addr, size_t count)
282 if (tag == X86_BUS_SPACE_IO)
283 insb(bsh + offset, addr, count);
285 #ifdef __GNUCLIKE_ASM
286 __asm __volatile(" \n\
288 1: movb (%2),%%al \n\
291 "=D" (addr), "=c" (count) :
292 "r" (bsh + offset), "0" (addr), "1" (count) :
299 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
300 bus_size_t offset, u_int16_t *addr, size_t count)
303 if (tag == X86_BUS_SPACE_IO)
304 insw(bsh + offset, addr, count);
306 #ifdef __GNUCLIKE_ASM
307 __asm __volatile(" \n\
309 1: movw (%2),%%ax \n\
312 "=D" (addr), "=c" (count) :
313 "r" (bsh + offset), "0" (addr), "1" (count) :
320 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
321 bus_size_t offset, u_int32_t *addr, size_t count)
324 if (tag == X86_BUS_SPACE_IO)
325 insl(bsh + offset, addr, count);
327 #ifdef __GNUCLIKE_ASM
328 __asm __volatile(" \n\
330 1: movl (%2),%%eax \n\
333 "=D" (addr), "=c" (count) :
334 "r" (bsh + offset), "0" (addr), "1" (count) :
340 #if 0 /* Cause a link error for bus_space_read_multi_8 */
341 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
345 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
346 * described by tag/handle and starting at `offset' and copy into
349 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
350 bus_space_handle_t bsh,
351 bus_size_t offset, u_int8_t *addr,
354 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
355 bus_space_handle_t bsh,
356 bus_size_t offset, u_int16_t *addr,
359 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
360 bus_space_handle_t bsh,
361 bus_size_t offset, u_int32_t *addr,
366 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
367 bus_size_t offset, u_int8_t *addr, size_t count)
370 if (tag == X86_BUS_SPACE_IO) {
371 int _port_ = bsh + offset;
372 #ifdef __GNUCLIKE_ASM
373 __asm __volatile(" \n\
379 "=D" (addr), "=c" (count), "=d" (_port_) :
380 "0" (addr), "1" (count), "2" (_port_) :
381 "%eax", "memory", "cc");
384 bus_space_handle_t _port_ = bsh + offset;
385 #ifdef __GNUCLIKE_ASM
386 __asm __volatile(" \n\
390 "=D" (addr), "=c" (count), "=S" (_port_) :
391 "0" (addr), "1" (count), "2" (_port_) :
398 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
399 bus_size_t offset, u_int16_t *addr, size_t count)
402 if (tag == X86_BUS_SPACE_IO) {
403 int _port_ = bsh + offset;
404 #ifdef __GNUCLIKE_ASM
405 __asm __volatile(" \n\
411 "=D" (addr), "=c" (count), "=d" (_port_) :
412 "0" (addr), "1" (count), "2" (_port_) :
413 "%eax", "memory", "cc");
416 bus_space_handle_t _port_ = bsh + offset;
417 #ifdef __GNUCLIKE_ASM
418 __asm __volatile(" \n\
422 "=D" (addr), "=c" (count), "=S" (_port_) :
423 "0" (addr), "1" (count), "2" (_port_) :
430 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
431 bus_size_t offset, u_int32_t *addr, size_t count)
434 if (tag == X86_BUS_SPACE_IO) {
435 int _port_ = bsh + offset;
436 #ifdef __GNUCLIKE_ASM
437 __asm __volatile(" \n\
443 "=D" (addr), "=c" (count), "=d" (_port_) :
444 "0" (addr), "1" (count), "2" (_port_) :
445 "%eax", "memory", "cc");
448 bus_space_handle_t _port_ = bsh + offset;
449 #ifdef __GNUCLIKE_ASM
450 __asm __volatile(" \n\
454 "=D" (addr), "=c" (count), "=S" (_port_) :
455 "0" (addr), "1" (count), "2" (_port_) :
461 #if 0 /* Cause a link error for bus_space_read_region_8 */
462 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
466 * Write the 1, 2, 4, or 8 byte value `value' to bus space
467 * described by tag/handle/offset.
470 static __inline void bus_space_write_1(bus_space_tag_t tag,
471 bus_space_handle_t bsh,
472 bus_size_t offset, u_int8_t value);
474 static __inline void bus_space_write_2(bus_space_tag_t tag,
475 bus_space_handle_t bsh,
476 bus_size_t offset, u_int16_t value);
478 static __inline void bus_space_write_4(bus_space_tag_t tag,
479 bus_space_handle_t bsh,
480 bus_size_t offset, u_int32_t value);
483 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
484 bus_size_t offset, u_int8_t value)
487 if (tag == X86_BUS_SPACE_IO)
488 outb(bsh + offset, value);
490 *(volatile u_int8_t *)(bsh + offset) = value;
494 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
495 bus_size_t offset, u_int16_t value)
498 if (tag == X86_BUS_SPACE_IO)
499 outw(bsh + offset, value);
501 *(volatile u_int16_t *)(bsh + offset) = value;
505 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
506 bus_size_t offset, u_int32_t value)
509 if (tag == X86_BUS_SPACE_IO)
510 outl(bsh + offset, value);
512 *(volatile u_int32_t *)(bsh + offset) = value;
515 #if 0 /* Cause a link error for bus_space_write_8 */
516 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
520 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
521 * provided to bus space described by tag/handle/offset.
524 static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
525 bus_space_handle_t bsh,
527 const u_int8_t *addr,
529 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
530 bus_space_handle_t bsh,
532 const u_int16_t *addr,
535 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
536 bus_space_handle_t bsh,
538 const u_int32_t *addr,
542 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
543 bus_size_t offset, const u_int8_t *addr, size_t count)
546 if (tag == X86_BUS_SPACE_IO)
547 outsb(bsh + offset, addr, count);
549 #ifdef __GNUCLIKE_ASM
550 __asm __volatile(" \n\
555 "=S" (addr), "=c" (count) :
556 "r" (bsh + offset), "0" (addr), "1" (count) :
557 "%eax", "memory", "cc");
563 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
564 bus_size_t offset, const u_int16_t *addr, size_t count)
567 if (tag == X86_BUS_SPACE_IO)
568 outsw(bsh + offset, addr, count);
570 #ifdef __GNUCLIKE_ASM
571 __asm __volatile(" \n\
576 "=S" (addr), "=c" (count) :
577 "r" (bsh + offset), "0" (addr), "1" (count) :
578 "%eax", "memory", "cc");
584 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
585 bus_size_t offset, const u_int32_t *addr, size_t count)
588 if (tag == X86_BUS_SPACE_IO)
589 outsl(bsh + offset, addr, count);
591 #ifdef __GNUCLIKE_ASM
592 __asm __volatile(" \n\
597 "=S" (addr), "=c" (count) :
598 "r" (bsh + offset), "0" (addr), "1" (count) :
599 "%eax", "memory", "cc");
604 #if 0 /* Cause a link error for bus_space_write_multi_8 */
605 #define bus_space_write_multi_8(t, h, o, a, c) \
606 !!! bus_space_write_multi_8 unimplemented !!!
610 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
611 * to bus space described by tag/handle starting at `offset'.
614 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
615 bus_space_handle_t bsh,
617 const u_int8_t *addr,
619 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
620 bus_space_handle_t bsh,
622 const u_int16_t *addr,
624 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
625 bus_space_handle_t bsh,
627 const u_int32_t *addr,
631 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
632 bus_size_t offset, const u_int8_t *addr, size_t count)
635 if (tag == X86_BUS_SPACE_IO) {
636 int _port_ = bsh + offset;
637 #ifdef __GNUCLIKE_ASM
638 __asm __volatile(" \n\
644 "=d" (_port_), "=S" (addr), "=c" (count) :
645 "0" (_port_), "1" (addr), "2" (count) :
646 "%eax", "memory", "cc");
649 bus_space_handle_t _port_ = bsh + offset;
650 #ifdef __GNUCLIKE_ASM
651 __asm __volatile(" \n\
655 "=D" (_port_), "=S" (addr), "=c" (count) :
656 "0" (_port_), "1" (addr), "2" (count) :
663 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
664 bus_size_t offset, const u_int16_t *addr, size_t count)
667 if (tag == X86_BUS_SPACE_IO) {
668 int _port_ = bsh + offset;
669 #ifdef __GNUCLIKE_ASM
670 __asm __volatile(" \n\
676 "=d" (_port_), "=S" (addr), "=c" (count) :
677 "0" (_port_), "1" (addr), "2" (count) :
678 "%eax", "memory", "cc");
681 bus_space_handle_t _port_ = bsh + offset;
682 #ifdef __GNUCLIKE_ASM
683 __asm __volatile(" \n\
687 "=D" (_port_), "=S" (addr), "=c" (count) :
688 "0" (_port_), "1" (addr), "2" (count) :
695 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
696 bus_size_t offset, const u_int32_t *addr, size_t count)
699 if (tag == X86_BUS_SPACE_IO) {
700 int _port_ = bsh + offset;
701 #ifdef __GNUCLIKE_ASM
702 __asm __volatile(" \n\
708 "=d" (_port_), "=S" (addr), "=c" (count) :
709 "0" (_port_), "1" (addr), "2" (count) :
710 "%eax", "memory", "cc");
713 bus_space_handle_t _port_ = bsh + offset;
714 #ifdef __GNUCLIKE_ASM
715 __asm __volatile(" \n\
719 "=D" (_port_), "=S" (addr), "=c" (count) :
720 "0" (_port_), "1" (addr), "2" (count) :
726 #if 0 /* Cause a link error for bus_space_write_region_8 */
727 #define bus_space_write_region_8 \
728 !!! bus_space_write_region_8 unimplemented !!!
732 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
733 * by tag/handle/offset `count' times.
736 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
737 bus_space_handle_t bsh,
739 u_int8_t value, size_t count);
740 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
741 bus_space_handle_t bsh,
743 u_int16_t value, size_t count);
744 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
745 bus_space_handle_t bsh,
747 u_int32_t value, size_t count);
750 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
751 bus_size_t offset, u_int8_t value, size_t count)
753 bus_space_handle_t addr = bsh + offset;
755 if (tag == X86_BUS_SPACE_IO)
760 *(volatile u_int8_t *)(addr) = value;
764 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
765 bus_size_t offset, u_int16_t value, size_t count)
767 bus_space_handle_t addr = bsh + offset;
769 if (tag == X86_BUS_SPACE_IO)
774 *(volatile u_int16_t *)(addr) = value;
778 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
779 bus_size_t offset, u_int32_t value, size_t count)
781 bus_space_handle_t addr = bsh + offset;
783 if (tag == X86_BUS_SPACE_IO)
788 *(volatile u_int32_t *)(addr) = value;
791 #if 0 /* Cause a link error for bus_space_set_multi_8 */
792 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
796 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
797 * by tag/handle starting at `offset'.
800 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
801 bus_space_handle_t bsh,
802 bus_size_t offset, u_int8_t value,
804 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
805 bus_space_handle_t bsh,
806 bus_size_t offset, u_int16_t value,
808 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
809 bus_space_handle_t bsh,
810 bus_size_t offset, u_int32_t value,
814 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
815 bus_size_t offset, u_int8_t value, size_t count)
817 bus_space_handle_t addr = bsh + offset;
819 if (tag == X86_BUS_SPACE_IO)
820 for (; count != 0; count--, addr++)
823 for (; count != 0; count--, addr++)
824 *(volatile u_int8_t *)(addr) = value;
828 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
829 bus_size_t offset, u_int16_t value, size_t count)
831 bus_space_handle_t addr = bsh + offset;
833 if (tag == X86_BUS_SPACE_IO)
834 for (; count != 0; count--, addr += 2)
837 for (; count != 0; count--, addr += 2)
838 *(volatile u_int16_t *)(addr) = value;
842 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
843 bus_size_t offset, u_int32_t value, size_t count)
845 bus_space_handle_t addr = bsh + offset;
847 if (tag == X86_BUS_SPACE_IO)
848 for (; count != 0; count--, addr += 4)
851 for (; count != 0; count--, addr += 4)
852 *(volatile u_int32_t *)(addr) = value;
855 #if 0 /* Cause a link error for bus_space_set_region_8 */
856 #define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
860 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
861 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
864 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
865 bus_space_handle_t bsh1,
867 bus_space_handle_t bsh2,
868 bus_size_t off2, size_t count);
870 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
871 bus_space_handle_t bsh1,
873 bus_space_handle_t bsh2,
874 bus_size_t off2, size_t count);
876 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
877 bus_space_handle_t bsh1,
879 bus_space_handle_t bsh2,
880 bus_size_t off2, size_t count);
883 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
884 bus_size_t off1, bus_space_handle_t bsh2,
885 bus_size_t off2, size_t count)
887 bus_space_handle_t addr1 = bsh1 + off1;
888 bus_space_handle_t addr2 = bsh2 + off2;
890 if (tag == X86_BUS_SPACE_IO) {
891 if (addr1 >= addr2) {
892 /* src after dest: copy forward */
893 for (; count != 0; count--, addr1++, addr2++)
894 outb(addr2, inb(addr1));
896 /* dest after src: copy backwards */
897 for (addr1 += (count - 1), addr2 += (count - 1);
898 count != 0; count--, addr1--, addr2--)
899 outb(addr2, inb(addr1));
902 if (addr1 >= addr2) {
903 /* src after dest: copy forward */
904 for (; count != 0; count--, addr1++, addr2++)
905 *(volatile u_int8_t *)(addr2) =
906 *(volatile u_int8_t *)(addr1);
908 /* dest after src: copy backwards */
909 for (addr1 += (count - 1), addr2 += (count - 1);
910 count != 0; count--, addr1--, addr2--)
911 *(volatile u_int8_t *)(addr2) =
912 *(volatile u_int8_t *)(addr1);
918 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
919 bus_size_t off1, bus_space_handle_t bsh2,
920 bus_size_t off2, size_t count)
922 bus_space_handle_t addr1 = bsh1 + off1;
923 bus_space_handle_t addr2 = bsh2 + off2;
925 if (tag == X86_BUS_SPACE_IO) {
926 if (addr1 >= addr2) {
927 /* src after dest: copy forward */
928 for (; count != 0; count--, addr1 += 2, addr2 += 2)
929 outw(addr2, inw(addr1));
931 /* dest after src: copy backwards */
932 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
933 count != 0; count--, addr1 -= 2, addr2 -= 2)
934 outw(addr2, inw(addr1));
937 if (addr1 >= addr2) {
938 /* src after dest: copy forward */
939 for (; count != 0; count--, addr1 += 2, addr2 += 2)
940 *(volatile u_int16_t *)(addr2) =
941 *(volatile u_int16_t *)(addr1);
943 /* dest after src: copy backwards */
944 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
945 count != 0; count--, addr1 -= 2, addr2 -= 2)
946 *(volatile u_int16_t *)(addr2) =
947 *(volatile u_int16_t *)(addr1);
953 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
954 bus_size_t off1, bus_space_handle_t bsh2,
955 bus_size_t off2, size_t count)
957 bus_space_handle_t addr1 = bsh1 + off1;
958 bus_space_handle_t addr2 = bsh2 + off2;
960 if (tag == X86_BUS_SPACE_IO) {
961 if (addr1 >= addr2) {
962 /* src after dest: copy forward */
963 for (; count != 0; count--, addr1 += 4, addr2 += 4)
964 outl(addr2, inl(addr1));
966 /* dest after src: copy backwards */
967 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
968 count != 0; count--, addr1 -= 4, addr2 -= 4)
969 outl(addr2, inl(addr1));
972 if (addr1 >= addr2) {
973 /* src after dest: copy forward */
974 for (; count != 0; count--, addr1 += 4, addr2 += 4)
975 *(volatile u_int32_t *)(addr2) =
976 *(volatile u_int32_t *)(addr1);
978 /* dest after src: copy backwards */
979 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
980 count != 0; count--, addr1 -= 4, addr2 -= 4)
981 *(volatile u_int32_t *)(addr2) =
982 *(volatile u_int32_t *)(addr1);
987 #if 0 /* Cause a link error for bus_space_copy_8 */
988 #define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
992 * Bus read/write barrier methods.
994 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
995 * bus_size_t offset, bus_size_t len, int flags);
998 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
999 * prevent reordering by the compiler; all Intel x86 processors currently
1000 * retire operations outside the CPU in program order.
1002 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
1003 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
1005 static __inline void
1006 bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
1007 bus_size_t offset __unused, bus_size_t len __unused, int flags)
1009 #ifdef __GNUCLIKE_ASM
1010 if (flags & BUS_SPACE_BARRIER_READ)
1012 __asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
1014 __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
1017 __asm __volatile("" : : : "memory");
1021 #ifdef BUS_SPACE_NO_LEGACY
1024 #define inb(a) compiler_error
1025 #define inw(a) compiler_error
1026 #define inl(a) compiler_error
1027 #define outb(a, b) compiler_error
1028 #define outw(a, b) compiler_error
1029 #define outl(a, b) compiler_error
1032 #include <machine/bus_dma.h>
1035 * Stream accesses are the same as normal accesses on x86; there are no
1036 * supported bus systems with an endianess different from the host one.
1038 #define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o))
1039 #define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o))
1040 #define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o))
1042 #define bus_space_read_multi_stream_1(t, h, o, a, c) \
1043 bus_space_read_multi_1((t), (h), (o), (a), (c))
1044 #define bus_space_read_multi_stream_2(t, h, o, a, c) \
1045 bus_space_read_multi_2((t), (h), (o), (a), (c))
1046 #define bus_space_read_multi_stream_4(t, h, o, a, c) \
1047 bus_space_read_multi_4((t), (h), (o), (a), (c))
1049 #define bus_space_write_stream_1(t, h, o, v) \
1050 bus_space_write_1((t), (h), (o), (v))
1051 #define bus_space_write_stream_2(t, h, o, v) \
1052 bus_space_write_2((t), (h), (o), (v))
1053 #define bus_space_write_stream_4(t, h, o, v) \
1054 bus_space_write_4((t), (h), (o), (v))
1056 #define bus_space_write_multi_stream_1(t, h, o, a, c) \
1057 bus_space_write_multi_1((t), (h), (o), (a), (c))
1058 #define bus_space_write_multi_stream_2(t, h, o, a, c) \
1059 bus_space_write_multi_2((t), (h), (o), (a), (c))
1060 #define bus_space_write_multi_stream_4(t, h, o, a, c) \
1061 bus_space_write_multi_4((t), (h), (o), (a), (c))
1063 #define bus_space_set_multi_stream_1(t, h, o, v, c) \
1064 bus_space_set_multi_1((t), (h), (o), (v), (c))
1065 #define bus_space_set_multi_stream_2(t, h, o, v, c) \
1066 bus_space_set_multi_2((t), (h), (o), (v), (c))
1067 #define bus_space_set_multi_stream_4(t, h, o, v, c) \
1068 bus_space_set_multi_4((t), (h), (o), (v), (c))
1070 #define bus_space_read_region_stream_1(t, h, o, a, c) \
1071 bus_space_read_region_1((t), (h), (o), (a), (c))
1072 #define bus_space_read_region_stream_2(t, h, o, a, c) \
1073 bus_space_read_region_2((t), (h), (o), (a), (c))
1074 #define bus_space_read_region_stream_4(t, h, o, a, c) \
1075 bus_space_read_region_4((t), (h), (o), (a), (c))
1077 #define bus_space_write_region_stream_1(t, h, o, a, c) \
1078 bus_space_write_region_1((t), (h), (o), (a), (c))
1079 #define bus_space_write_region_stream_2(t, h, o, a, c) \
1080 bus_space_write_region_2((t), (h), (o), (a), (c))
1081 #define bus_space_write_region_stream_4(t, h, o, a, c) \
1082 bus_space_write_region_4((t), (h), (o), (a), (c))
1084 #define bus_space_set_region_stream_1(t, h, o, v, c) \
1085 bus_space_set_region_1((t), (h), (o), (v), (c))
1086 #define bus_space_set_region_stream_2(t, h, o, v, c) \
1087 bus_space_set_region_2((t), (h), (o), (v), (c))
1088 #define bus_space_set_region_stream_4(t, h, o, v, c) \
1089 bus_space_set_region_4((t), (h), (o), (v), (c))
1091 #define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
1092 bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
1093 #define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
1094 bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
1095 #define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
1096 bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
1098 #endif /* _X86_BUS_H_ */