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>
111 * Values for the i386 bus space tag, not to be used directly by MI code.
113 #define I386_BUS_SPACE_IO 0 /* space is i/o space */
114 #define I386_BUS_SPACE_MEM 1 /* space is mem space */
116 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
117 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
118 #define BUS_SPACE_MAXSIZE 0xFFFFFFFF
119 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
120 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
122 #define BUS_SPACE_MAXADDR 0xFFFFFFFFFFFFFFFFULL
124 #define BUS_SPACE_MAXADDR 0xFFFFFFFF
127 #define BUS_SPACE_UNRESTRICTED (~0)
130 * Map a region of device bus space into CPU virtual address space.
133 static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
134 bus_size_t size, int flags,
135 bus_space_handle_t *bshp);
138 bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
139 bus_size_t size __unused, int flags __unused,
140 bus_space_handle_t *bshp)
148 * Unmap a region of device bus space.
151 static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
155 bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
156 bus_size_t size __unused)
161 * Get a new handle for a subregion of an already-mapped area of bus space.
164 static __inline int bus_space_subregion(bus_space_tag_t t,
165 bus_space_handle_t bsh,
166 bus_size_t offset, bus_size_t size,
167 bus_space_handle_t *nbshp);
170 bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
171 bus_size_t offset, bus_size_t size __unused,
172 bus_space_handle_t *nbshp)
175 *nbshp = bsh + offset;
180 * Allocate a region of memory that is accessible to devices in bus space.
183 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
184 bus_addr_t rend, bus_size_t size, bus_size_t align,
185 bus_size_t boundary, int flags, bus_addr_t *addrp,
186 bus_space_handle_t *bshp);
189 * Free a region of bus space accessible memory.
192 static __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
196 bus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
197 bus_size_t size __unused)
203 * Read a 1, 2, 4, or 8 byte quantity from bus space
204 * described by tag/handle/offset.
206 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
207 bus_space_handle_t handle,
210 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
211 bus_space_handle_t handle,
214 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
215 bus_space_handle_t handle,
218 static __inline u_int8_t
219 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
223 if (tag == I386_BUS_SPACE_IO)
224 return (inb(handle + offset));
225 return (*(volatile u_int8_t *)(handle + offset));
228 static __inline u_int16_t
229 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
233 if (tag == I386_BUS_SPACE_IO)
234 return (inw(handle + offset));
235 return (*(volatile u_int16_t *)(handle + offset));
238 static __inline u_int32_t
239 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
243 if (tag == I386_BUS_SPACE_IO)
244 return (inl(handle + offset));
245 return (*(volatile u_int32_t *)(handle + offset));
248 #if 0 /* Cause a link error for bus_space_read_8 */
249 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
253 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
254 * described by tag/handle/offset and copy into buffer provided.
256 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
257 bus_space_handle_t bsh,
258 bus_size_t offset, u_int8_t *addr,
261 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
262 bus_space_handle_t bsh,
263 bus_size_t offset, u_int16_t *addr,
266 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
267 bus_space_handle_t bsh,
268 bus_size_t offset, u_int32_t *addr,
272 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
273 bus_size_t offset, u_int8_t *addr, size_t count)
276 if (tag == I386_BUS_SPACE_IO)
277 insb(bsh + offset, addr, count);
279 #ifdef __GNUCLIKE_ASM
280 __asm __volatile(" \n\
282 1: movb (%2),%%al \n\
285 "=D" (addr), "=c" (count) :
286 "r" (bsh + offset), "0" (addr), "1" (count) :
290 # error "no assembler code for your compiler"
297 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
298 bus_size_t offset, u_int16_t *addr, size_t count)
301 if (tag == I386_BUS_SPACE_IO)
302 insw(bsh + offset, addr, count);
304 #ifdef __GNUCLIKE_ASM
305 __asm __volatile(" \n\
307 1: movw (%2),%%ax \n\
310 "=D" (addr), "=c" (count) :
311 "r" (bsh + offset), "0" (addr), "1" (count) :
315 # error "no assembler code for your compiler"
322 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
323 bus_size_t offset, u_int32_t *addr, size_t count)
326 if (tag == I386_BUS_SPACE_IO)
327 insl(bsh + offset, addr, count);
329 #ifdef __GNUCLIKE_ASM
330 __asm __volatile(" \n\
332 1: movl (%2),%%eax \n\
335 "=D" (addr), "=c" (count) :
336 "r" (bsh + offset), "0" (addr), "1" (count) :
340 # error "no assembler code for your compiler"
346 #if 0 /* Cause a link error for bus_space_read_multi_8 */
347 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
351 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
352 * described by tag/handle and starting at `offset' and copy into
355 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
356 bus_space_handle_t bsh,
357 bus_size_t offset, u_int8_t *addr,
360 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
361 bus_space_handle_t bsh,
362 bus_size_t offset, u_int16_t *addr,
365 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
366 bus_space_handle_t bsh,
367 bus_size_t offset, u_int32_t *addr,
372 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
373 bus_size_t offset, u_int8_t *addr, size_t count)
376 if (tag == I386_BUS_SPACE_IO) {
377 int _port_ = bsh + offset;
378 #ifdef __GNUCLIKE_ASM
379 __asm __volatile(" \n\
385 "=D" (addr), "=c" (count), "=d" (_port_) :
386 "0" (addr), "1" (count), "2" (_port_) :
387 "%eax", "memory", "cc");
390 # error "no assembler code for your compiler"
394 int _port_ = bsh + offset;
395 #ifdef __GNUCLIKE_ASM
396 __asm __volatile(" \n\
400 "=D" (addr), "=c" (count), "=S" (_port_) :
401 "0" (addr), "1" (count), "2" (_port_) :
405 # error "no assembler code for your compiler"
412 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
413 bus_size_t offset, u_int16_t *addr, size_t count)
416 if (tag == I386_BUS_SPACE_IO) {
417 int _port_ = bsh + offset;
418 #ifdef __GNUCLIKE_ASM
419 __asm __volatile(" \n\
425 "=D" (addr), "=c" (count), "=d" (_port_) :
426 "0" (addr), "1" (count), "2" (_port_) :
427 "%eax", "memory", "cc");
430 # error "no assembler code for your compiler"
434 int _port_ = bsh + offset;
435 #ifdef __GNUCLIKE_ASM
436 __asm __volatile(" \n\
440 "=D" (addr), "=c" (count), "=S" (_port_) :
441 "0" (addr), "1" (count), "2" (_port_) :
445 # error "no assembler code for your compiler"
452 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
453 bus_size_t offset, u_int32_t *addr, size_t count)
456 if (tag == I386_BUS_SPACE_IO) {
457 int _port_ = bsh + offset;
458 #ifdef __GNUCLIKE_ASM
459 __asm __volatile(" \n\
465 "=D" (addr), "=c" (count), "=d" (_port_) :
466 "0" (addr), "1" (count), "2" (_port_) :
467 "%eax", "memory", "cc");
470 # error "no assembler code for your compiler"
474 int _port_ = bsh + offset;
475 #ifdef __GNUCLIKE_ASM
476 __asm __volatile(" \n\
480 "=D" (addr), "=c" (count), "=S" (_port_) :
481 "0" (addr), "1" (count), "2" (_port_) :
485 # error "no assembler code for your compiler"
491 #if 0 /* Cause a link error for bus_space_read_region_8 */
492 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
496 * Write the 1, 2, 4, or 8 byte value `value' to bus space
497 * described by tag/handle/offset.
500 static __inline void bus_space_write_1(bus_space_tag_t tag,
501 bus_space_handle_t bsh,
502 bus_size_t offset, u_int8_t value);
504 static __inline void bus_space_write_2(bus_space_tag_t tag,
505 bus_space_handle_t bsh,
506 bus_size_t offset, u_int16_t value);
508 static __inline void bus_space_write_4(bus_space_tag_t tag,
509 bus_space_handle_t bsh,
510 bus_size_t offset, u_int32_t value);
513 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
514 bus_size_t offset, u_int8_t value)
517 if (tag == I386_BUS_SPACE_IO)
518 outb(bsh + offset, value);
520 *(volatile u_int8_t *)(bsh + offset) = value;
524 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
525 bus_size_t offset, u_int16_t value)
528 if (tag == I386_BUS_SPACE_IO)
529 outw(bsh + offset, value);
531 *(volatile u_int16_t *)(bsh + offset) = value;
535 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
536 bus_size_t offset, u_int32_t value)
539 if (tag == I386_BUS_SPACE_IO)
540 outl(bsh + offset, value);
542 *(volatile u_int32_t *)(bsh + offset) = value;
545 #if 0 /* Cause a link error for bus_space_write_8 */
546 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
550 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
551 * provided to bus space described by tag/handle/offset.
554 static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
555 bus_space_handle_t bsh,
557 const u_int8_t *addr,
559 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
560 bus_space_handle_t bsh,
562 const u_int16_t *addr,
565 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
566 bus_space_handle_t bsh,
568 const u_int32_t *addr,
572 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
573 bus_size_t offset, const u_int8_t *addr, size_t count)
576 if (tag == I386_BUS_SPACE_IO)
577 outsb(bsh + offset, addr, count);
579 #ifdef __GNUCLIKE_ASM
580 __asm __volatile(" \n\
585 "=S" (addr), "=c" (count) :
586 "r" (bsh + offset), "0" (addr), "1" (count) :
587 "%eax", "memory", "cc");
590 # error "no assembler code for your compiler"
597 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
598 bus_size_t offset, const u_int16_t *addr, size_t count)
601 if (tag == I386_BUS_SPACE_IO)
602 outsw(bsh + offset, addr, count);
604 #ifdef __GNUCLIKE_ASM
605 __asm __volatile(" \n\
610 "=S" (addr), "=c" (count) :
611 "r" (bsh + offset), "0" (addr), "1" (count) :
612 "%eax", "memory", "cc");
615 # error "no assembler code for your compiler"
622 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
623 bus_size_t offset, const u_int32_t *addr, size_t count)
626 if (tag == I386_BUS_SPACE_IO)
627 outsl(bsh + offset, addr, count);
629 #ifdef __GNUCLIKE_ASM
630 __asm __volatile(" \n\
635 "=S" (addr), "=c" (count) :
636 "r" (bsh + offset), "0" (addr), "1" (count) :
637 "%eax", "memory", "cc");
640 # error "no assembler code for your compiler"
646 #if 0 /* Cause a link error for bus_space_write_multi_8 */
647 #define bus_space_write_multi_8(t, h, o, a, c) \
648 !!! bus_space_write_multi_8 unimplemented !!!
652 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
653 * to bus space described by tag/handle starting at `offset'.
656 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
657 bus_space_handle_t bsh,
659 const u_int8_t *addr,
661 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
662 bus_space_handle_t bsh,
664 const u_int16_t *addr,
666 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
667 bus_space_handle_t bsh,
669 const u_int32_t *addr,
673 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
674 bus_size_t offset, const u_int8_t *addr, size_t count)
677 if (tag == I386_BUS_SPACE_IO) {
678 int _port_ = bsh + offset;
679 #ifdef __GNUCLIKE_ASM
680 __asm __volatile(" \n\
686 "=d" (_port_), "=S" (addr), "=c" (count) :
687 "0" (_port_), "1" (addr), "2" (count) :
688 "%eax", "memory", "cc");
691 # error "no assembler code for your compiler"
695 int _port_ = bsh + offset;
696 #ifdef __GNUCLIKE_ASM
697 __asm __volatile(" \n\
701 "=D" (_port_), "=S" (addr), "=c" (count) :
702 "0" (_port_), "1" (addr), "2" (count) :
706 # error "no assembler code for your compiler"
713 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
714 bus_size_t offset, const u_int16_t *addr, size_t count)
717 if (tag == I386_BUS_SPACE_IO) {
718 int _port_ = bsh + offset;
719 #ifdef __GNUCLIKE_ASM
720 __asm __volatile(" \n\
726 "=d" (_port_), "=S" (addr), "=c" (count) :
727 "0" (_port_), "1" (addr), "2" (count) :
728 "%eax", "memory", "cc");
731 # error "no assembler code for your compiler"
735 int _port_ = bsh + offset;
736 #ifdef __GNUCLIKE_ASM
737 __asm __volatile(" \n\
741 "=D" (_port_), "=S" (addr), "=c" (count) :
742 "0" (_port_), "1" (addr), "2" (count) :
746 # error "no assembler code for your compiler"
753 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
754 bus_size_t offset, const u_int32_t *addr, size_t count)
757 if (tag == I386_BUS_SPACE_IO) {
758 int _port_ = bsh + offset;
759 #ifdef __GNUCLIKE_ASM
760 __asm __volatile(" \n\
766 "=d" (_port_), "=S" (addr), "=c" (count) :
767 "0" (_port_), "1" (addr), "2" (count) :
768 "%eax", "memory", "cc");
771 # error "no assembler code for your compiler"
775 int _port_ = bsh + offset;
776 #ifdef __GNUCLIKE_ASM
777 __asm __volatile(" \n\
781 "=D" (_port_), "=S" (addr), "=c" (count) :
782 "0" (_port_), "1" (addr), "2" (count) :
786 # error "no assembler code for your compiler"
792 #if 0 /* Cause a link error for bus_space_write_region_8 */
793 #define bus_space_write_region_8 \
794 !!! bus_space_write_region_8 unimplemented !!!
798 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
799 * by tag/handle/offset `count' times.
802 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
803 bus_space_handle_t bsh,
805 u_int8_t value, size_t count);
806 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
807 bus_space_handle_t bsh,
809 u_int16_t value, size_t count);
810 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
811 bus_space_handle_t bsh,
813 u_int32_t value, size_t count);
816 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
817 bus_size_t offset, u_int8_t value, size_t count)
819 bus_space_handle_t addr = bsh + offset;
821 if (tag == I386_BUS_SPACE_IO)
826 *(volatile u_int8_t *)(addr) = value;
830 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
831 bus_size_t offset, u_int16_t value, size_t count)
833 bus_space_handle_t addr = bsh + offset;
835 if (tag == I386_BUS_SPACE_IO)
840 *(volatile u_int16_t *)(addr) = value;
844 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
845 bus_size_t offset, u_int32_t value, size_t count)
847 bus_space_handle_t addr = bsh + offset;
849 if (tag == I386_BUS_SPACE_IO)
854 *(volatile u_int32_t *)(addr) = value;
857 #if 0 /* Cause a link error for bus_space_set_multi_8 */
858 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
862 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
863 * by tag/handle starting at `offset'.
866 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
867 bus_space_handle_t bsh,
868 bus_size_t offset, u_int8_t value,
870 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
871 bus_space_handle_t bsh,
872 bus_size_t offset, u_int16_t value,
874 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
875 bus_space_handle_t bsh,
876 bus_size_t offset, u_int32_t value,
880 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
881 bus_size_t offset, u_int8_t value, size_t count)
883 bus_space_handle_t addr = bsh + offset;
885 if (tag == I386_BUS_SPACE_IO)
886 for (; count != 0; count--, addr++)
889 for (; count != 0; count--, addr++)
890 *(volatile u_int8_t *)(addr) = value;
894 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
895 bus_size_t offset, u_int16_t value, size_t count)
897 bus_space_handle_t addr = bsh + offset;
899 if (tag == I386_BUS_SPACE_IO)
900 for (; count != 0; count--, addr += 2)
903 for (; count != 0; count--, addr += 2)
904 *(volatile u_int16_t *)(addr) = value;
908 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
909 bus_size_t offset, u_int32_t value, size_t count)
911 bus_space_handle_t addr = bsh + offset;
913 if (tag == I386_BUS_SPACE_IO)
914 for (; count != 0; count--, addr += 4)
917 for (; count != 0; count--, addr += 4)
918 *(volatile u_int32_t *)(addr) = value;
921 #if 0 /* Cause a link error for bus_space_set_region_8 */
922 #define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
926 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
927 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
930 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
931 bus_space_handle_t bsh1,
933 bus_space_handle_t bsh2,
934 bus_size_t off2, size_t count);
936 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
937 bus_space_handle_t bsh1,
939 bus_space_handle_t bsh2,
940 bus_size_t off2, size_t count);
942 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
943 bus_space_handle_t bsh1,
945 bus_space_handle_t bsh2,
946 bus_size_t off2, size_t count);
949 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
950 bus_size_t off1, bus_space_handle_t bsh2,
951 bus_size_t off2, size_t count)
953 bus_space_handle_t addr1 = bsh1 + off1;
954 bus_space_handle_t addr2 = bsh2 + off2;
956 if (tag == I386_BUS_SPACE_IO) {
957 if (addr1 >= addr2) {
958 /* src after dest: copy forward */
959 for (; count != 0; count--, addr1++, addr2++)
960 outb(addr2, inb(addr1));
962 /* dest after src: copy backwards */
963 for (addr1 += (count - 1), addr2 += (count - 1);
964 count != 0; count--, addr1--, addr2--)
965 outb(addr2, inb(addr1));
968 if (addr1 >= addr2) {
969 /* src after dest: copy forward */
970 for (; count != 0; count--, addr1++, addr2++)
971 *(volatile u_int8_t *)(addr2) =
972 *(volatile u_int8_t *)(addr1);
974 /* dest after src: copy backwards */
975 for (addr1 += (count - 1), addr2 += (count - 1);
976 count != 0; count--, addr1--, addr2--)
977 *(volatile u_int8_t *)(addr2) =
978 *(volatile u_int8_t *)(addr1);
984 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
985 bus_size_t off1, bus_space_handle_t bsh2,
986 bus_size_t off2, size_t count)
988 bus_space_handle_t addr1 = bsh1 + off1;
989 bus_space_handle_t addr2 = bsh2 + off2;
991 if (tag == I386_BUS_SPACE_IO) {
992 if (addr1 >= addr2) {
993 /* src after dest: copy forward */
994 for (; count != 0; count--, addr1 += 2, addr2 += 2)
995 outw(addr2, inw(addr1));
997 /* dest after src: copy backwards */
998 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
999 count != 0; count--, addr1 -= 2, addr2 -= 2)
1000 outw(addr2, inw(addr1));
1003 if (addr1 >= addr2) {
1004 /* src after dest: copy forward */
1005 for (; count != 0; count--, addr1 += 2, addr2 += 2)
1006 *(volatile u_int16_t *)(addr2) =
1007 *(volatile u_int16_t *)(addr1);
1009 /* dest after src: copy backwards */
1010 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1011 count != 0; count--, addr1 -= 2, addr2 -= 2)
1012 *(volatile u_int16_t *)(addr2) =
1013 *(volatile u_int16_t *)(addr1);
1018 static __inline void
1019 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
1020 bus_size_t off1, bus_space_handle_t bsh2,
1021 bus_size_t off2, size_t count)
1023 bus_space_handle_t addr1 = bsh1 + off1;
1024 bus_space_handle_t addr2 = bsh2 + off2;
1026 if (tag == I386_BUS_SPACE_IO) {
1027 if (addr1 >= addr2) {
1028 /* src after dest: copy forward */
1029 for (; count != 0; count--, addr1 += 4, addr2 += 4)
1030 outl(addr2, inl(addr1));
1032 /* dest after src: copy backwards */
1033 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1034 count != 0; count--, addr1 -= 4, addr2 -= 4)
1035 outl(addr2, inl(addr1));
1038 if (addr1 >= addr2) {
1039 /* src after dest: copy forward */
1040 for (; count != 0; count--, addr1 += 4, addr2 += 4)
1041 *(volatile u_int32_t *)(addr2) =
1042 *(volatile u_int32_t *)(addr1);
1044 /* dest after src: copy backwards */
1045 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1046 count != 0; count--, addr1 -= 4, addr2 -= 4)
1047 *(volatile u_int32_t *)(addr2) =
1048 *(volatile u_int32_t *)(addr1);
1053 #if 0 /* Cause a link error for bus_space_copy_8 */
1054 #define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
1058 * Bus read/write barrier methods.
1060 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
1061 * bus_size_t offset, bus_size_t len, int flags);
1064 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
1065 * prevent reordering by the compiler; all Intel x86 processors currently
1066 * retire operations outside the CPU in program order.
1068 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
1069 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
1071 static __inline void
1072 bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
1073 bus_size_t offset __unused, bus_size_t len __unused, int flags)
1075 #ifdef __GNUCLIKE_ASM
1076 if (flags & BUS_SPACE_BARRIER_READ)
1077 __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
1079 __asm __volatile("" : : : "memory");
1082 # error "no assembler code for your compiler"
1087 #ifdef BUS_SPACE_NO_LEGACY
1090 #define inb(a) compiler_error
1091 #define inw(a) compiler_error
1092 #define inl(a) compiler_error
1093 #define outb(a, b) compiler_error
1094 #define outw(a, b) compiler_error
1095 #define outl(a, b) compiler_error
1098 #include <machine/bus_dma.h>
1101 * Stream accesses are the same as normal accesses on i386/pc98; there are no
1102 * supported bus systems with an endianess different from the host one.
1104 #define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o))
1105 #define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o))
1106 #define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o))
1108 #define bus_space_read_multi_stream_1(t, h, o, a, c) \
1109 bus_space_read_multi_1((t), (h), (o), (a), (c))
1110 #define bus_space_read_multi_stream_2(t, h, o, a, c) \
1111 bus_space_read_multi_2((t), (h), (o), (a), (c))
1112 #define bus_space_read_multi_stream_4(t, h, o, a, c) \
1113 bus_space_read_multi_4((t), (h), (o), (a), (c))
1115 #define bus_space_write_stream_1(t, h, o, v) \
1116 bus_space_write_1((t), (h), (o), (v))
1117 #define bus_space_write_stream_2(t, h, o, v) \
1118 bus_space_write_2((t), (h), (o), (v))
1119 #define bus_space_write_stream_4(t, h, o, v) \
1120 bus_space_write_4((t), (h), (o), (v))
1122 #define bus_space_write_multi_stream_1(t, h, o, a, c) \
1123 bus_space_write_multi_1((t), (h), (o), (a), (c))
1124 #define bus_space_write_multi_stream_2(t, h, o, a, c) \
1125 bus_space_write_multi_2((t), (h), (o), (a), (c))
1126 #define bus_space_write_multi_stream_4(t, h, o, a, c) \
1127 bus_space_write_multi_4((t), (h), (o), (a), (c))
1129 #define bus_space_set_multi_stream_1(t, h, o, v, c) \
1130 bus_space_set_multi_1((t), (h), (o), (v), (c))
1131 #define bus_space_set_multi_stream_2(t, h, o, v, c) \
1132 bus_space_set_multi_2((t), (h), (o), (v), (c))
1133 #define bus_space_set_multi_stream_4(t, h, o, v, c) \
1134 bus_space_set_multi_4((t), (h), (o), (v), (c))
1136 #define bus_space_read_region_stream_1(t, h, o, a, c) \
1137 bus_space_read_region_1((t), (h), (o), (a), (c))
1138 #define bus_space_read_region_stream_2(t, h, o, a, c) \
1139 bus_space_read_region_2((t), (h), (o), (a), (c))
1140 #define bus_space_read_region_stream_4(t, h, o, a, c) \
1141 bus_space_read_region_4((t), (h), (o), (a), (c))
1143 #define bus_space_write_region_stream_1(t, h, o, a, c) \
1144 bus_space_write_region_1((t), (h), (o), (a), (c))
1145 #define bus_space_write_region_stream_2(t, h, o, a, c) \
1146 bus_space_write_region_2((t), (h), (o), (a), (c))
1147 #define bus_space_write_region_stream_4(t, h, o, a, c) \
1148 bus_space_write_region_4((t), (h), (o), (a), (c))
1150 #define bus_space_set_region_stream_1(t, h, o, v, c) \
1151 bus_space_set_region_1((t), (h), (o), (v), (c))
1152 #define bus_space_set_region_stream_2(t, h, o, v, c) \
1153 bus_space_set_region_2((t), (h), (o), (v), (c))
1154 #define bus_space_set_region_stream_4(t, h, o, v, c) \
1155 bus_space_set_region_4((t), (h), (o), (v), (c))
1157 #define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
1158 bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
1159 #define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
1160 bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
1161 #define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
1162 bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
1164 #endif /* _I386_BUS_H_ */