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_INVALID_DATA (~0)
134 #define BUS_SPACE_UNRESTRICTED (~0)
137 * Map a region of device bus space into CPU virtual address space.
140 static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
141 bus_size_t size, int flags,
142 bus_space_handle_t *bshp);
145 bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr,
146 bus_size_t size __unused, int flags __unused,
147 bus_space_handle_t *bshp)
155 * Unmap a region of device bus space.
158 static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
162 bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
163 bus_size_t size __unused)
168 * Get a new handle for a subregion of an already-mapped area of bus space.
171 static __inline int bus_space_subregion(bus_space_tag_t t,
172 bus_space_handle_t bsh,
173 bus_size_t offset, bus_size_t size,
174 bus_space_handle_t *nbshp);
177 bus_space_subregion(bus_space_tag_t t __unused, bus_space_handle_t bsh,
178 bus_size_t offset, bus_size_t size __unused,
179 bus_space_handle_t *nbshp)
182 *nbshp = bsh + offset;
187 * Allocate a region of memory that is accessible to devices in bus space.
190 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
191 bus_addr_t rend, bus_size_t size, bus_size_t align,
192 bus_size_t boundary, int flags, bus_addr_t *addrp,
193 bus_space_handle_t *bshp);
196 * Free a region of bus space accessible memory.
199 static __inline void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
203 bus_space_free(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused,
204 bus_size_t size __unused)
210 * Read a 1, 2, 4, or 8 byte quantity from bus space
211 * described by tag/handle/offset.
213 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
214 bus_space_handle_t handle,
217 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
218 bus_space_handle_t handle,
221 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
222 bus_space_handle_t handle,
226 static __inline uint64_t bus_space_read_8(bus_space_tag_t tag,
227 bus_space_handle_t handle,
231 static __inline u_int8_t
232 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
236 if (tag == X86_BUS_SPACE_IO)
237 return (inb(handle + offset));
238 return (*(volatile u_int8_t *)(handle + offset));
241 static __inline u_int16_t
242 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
246 if (tag == X86_BUS_SPACE_IO)
247 return (inw(handle + offset));
248 return (*(volatile u_int16_t *)(handle + offset));
251 static __inline u_int32_t
252 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
256 if (tag == X86_BUS_SPACE_IO)
257 return (inl(handle + offset));
258 return (*(volatile u_int32_t *)(handle + offset));
262 static __inline uint64_t
263 bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle,
267 if (tag == X86_BUS_SPACE_IO) /* No 8 byte IO space access on x86 */
268 return (BUS_SPACE_INVALID_DATA);
269 return (*(volatile uint64_t *)(handle + offset));
274 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
275 * described by tag/handle/offset and copy into buffer provided.
277 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
278 bus_space_handle_t bsh,
279 bus_size_t offset, u_int8_t *addr,
282 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
283 bus_space_handle_t bsh,
284 bus_size_t offset, u_int16_t *addr,
287 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
288 bus_space_handle_t bsh,
289 bus_size_t offset, u_int32_t *addr,
293 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
294 bus_size_t offset, u_int8_t *addr, size_t count)
297 if (tag == X86_BUS_SPACE_IO)
298 insb(bsh + offset, addr, count);
300 #ifdef __GNUCLIKE_ASM
301 __asm __volatile(" \n\
303 1: movb (%2),%%al \n\
306 "=D" (addr), "=c" (count) :
307 "r" (bsh + offset), "0" (addr), "1" (count) :
314 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
315 bus_size_t offset, u_int16_t *addr, size_t count)
318 if (tag == X86_BUS_SPACE_IO)
319 insw(bsh + offset, addr, count);
321 #ifdef __GNUCLIKE_ASM
322 __asm __volatile(" \n\
324 1: movw (%2),%%ax \n\
327 "=D" (addr), "=c" (count) :
328 "r" (bsh + offset), "0" (addr), "1" (count) :
335 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
336 bus_size_t offset, u_int32_t *addr, size_t count)
339 if (tag == X86_BUS_SPACE_IO)
340 insl(bsh + offset, addr, count);
342 #ifdef __GNUCLIKE_ASM
343 __asm __volatile(" \n\
345 1: movl (%2),%%eax \n\
348 "=D" (addr), "=c" (count) :
349 "r" (bsh + offset), "0" (addr), "1" (count) :
355 #if 0 /* Cause a link error for bus_space_read_multi_8 */
356 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
360 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
361 * described by tag/handle and starting at `offset' and copy into
364 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
365 bus_space_handle_t bsh,
366 bus_size_t offset, u_int8_t *addr,
369 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
370 bus_space_handle_t bsh,
371 bus_size_t offset, u_int16_t *addr,
374 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
375 bus_space_handle_t bsh,
376 bus_size_t offset, u_int32_t *addr,
381 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
382 bus_size_t offset, u_int8_t *addr, size_t count)
385 if (tag == X86_BUS_SPACE_IO) {
386 int _port_ = bsh + offset;
387 #ifdef __GNUCLIKE_ASM
388 __asm __volatile(" \n\
394 "=D" (addr), "=c" (count), "=d" (_port_) :
395 "0" (addr), "1" (count), "2" (_port_) :
396 "%eax", "memory", "cc");
399 bus_space_handle_t _port_ = bsh + offset;
400 #ifdef __GNUCLIKE_ASM
401 __asm __volatile(" \n\
405 "=D" (addr), "=c" (count), "=S" (_port_) :
406 "0" (addr), "1" (count), "2" (_port_) :
413 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
414 bus_size_t offset, u_int16_t *addr, size_t count)
417 if (tag == X86_BUS_SPACE_IO) {
418 int _port_ = bsh + offset;
419 #ifdef __GNUCLIKE_ASM
420 __asm __volatile(" \n\
426 "=D" (addr), "=c" (count), "=d" (_port_) :
427 "0" (addr), "1" (count), "2" (_port_) :
428 "%eax", "memory", "cc");
431 bus_space_handle_t _port_ = bsh + offset;
432 #ifdef __GNUCLIKE_ASM
433 __asm __volatile(" \n\
437 "=D" (addr), "=c" (count), "=S" (_port_) :
438 "0" (addr), "1" (count), "2" (_port_) :
445 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
446 bus_size_t offset, u_int32_t *addr, size_t count)
449 if (tag == X86_BUS_SPACE_IO) {
450 int _port_ = bsh + offset;
451 #ifdef __GNUCLIKE_ASM
452 __asm __volatile(" \n\
458 "=D" (addr), "=c" (count), "=d" (_port_) :
459 "0" (addr), "1" (count), "2" (_port_) :
460 "%eax", "memory", "cc");
463 bus_space_handle_t _port_ = bsh + offset;
464 #ifdef __GNUCLIKE_ASM
465 __asm __volatile(" \n\
469 "=D" (addr), "=c" (count), "=S" (_port_) :
470 "0" (addr), "1" (count), "2" (_port_) :
476 #if 0 /* Cause a link error for bus_space_read_region_8 */
477 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
481 * Write the 1, 2, 4, or 8 byte value `value' to bus space
482 * described by tag/handle/offset.
485 static __inline void bus_space_write_1(bus_space_tag_t tag,
486 bus_space_handle_t bsh,
487 bus_size_t offset, u_int8_t value);
489 static __inline void bus_space_write_2(bus_space_tag_t tag,
490 bus_space_handle_t bsh,
491 bus_size_t offset, u_int16_t value);
493 static __inline void bus_space_write_4(bus_space_tag_t tag,
494 bus_space_handle_t bsh,
495 bus_size_t offset, u_int32_t value);
498 static __inline void bus_space_write_8(bus_space_tag_t tag,
499 bus_space_handle_t bsh,
500 bus_size_t offset, uint64_t value);
504 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
505 bus_size_t offset, u_int8_t value)
508 if (tag == X86_BUS_SPACE_IO)
509 outb(bsh + offset, value);
511 *(volatile u_int8_t *)(bsh + offset) = value;
515 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
516 bus_size_t offset, u_int16_t value)
519 if (tag == X86_BUS_SPACE_IO)
520 outw(bsh + offset, value);
522 *(volatile u_int16_t *)(bsh + offset) = value;
526 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
527 bus_size_t offset, u_int32_t value)
530 if (tag == X86_BUS_SPACE_IO)
531 outl(bsh + offset, value);
533 *(volatile u_int32_t *)(bsh + offset) = value;
538 bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t bsh,
539 bus_size_t offset, uint64_t value)
542 if (tag == X86_BUS_SPACE_IO) /* No 8 byte IO space access on x86 */
545 *(volatile uint64_t *)(bsh + offset) = value;
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 == X86_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");
593 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
594 bus_size_t offset, const u_int16_t *addr, size_t count)
597 if (tag == X86_BUS_SPACE_IO)
598 outsw(bsh + offset, addr, count);
600 #ifdef __GNUCLIKE_ASM
601 __asm __volatile(" \n\
606 "=S" (addr), "=c" (count) :
607 "r" (bsh + offset), "0" (addr), "1" (count) :
608 "%eax", "memory", "cc");
614 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
615 bus_size_t offset, const u_int32_t *addr, size_t count)
618 if (tag == X86_BUS_SPACE_IO)
619 outsl(bsh + offset, addr, count);
621 #ifdef __GNUCLIKE_ASM
622 __asm __volatile(" \n\
627 "=S" (addr), "=c" (count) :
628 "r" (bsh + offset), "0" (addr), "1" (count) :
629 "%eax", "memory", "cc");
634 #if 0 /* Cause a link error for bus_space_write_multi_8 */
635 #define bus_space_write_multi_8(t, h, o, a, c) \
636 !!! bus_space_write_multi_8 unimplemented !!!
640 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
641 * to bus space described by tag/handle starting at `offset'.
644 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
645 bus_space_handle_t bsh,
647 const u_int8_t *addr,
649 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
650 bus_space_handle_t bsh,
652 const u_int16_t *addr,
654 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
655 bus_space_handle_t bsh,
657 const u_int32_t *addr,
661 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
662 bus_size_t offset, const u_int8_t *addr, size_t count)
665 if (tag == X86_BUS_SPACE_IO) {
666 int _port_ = bsh + offset;
667 #ifdef __GNUCLIKE_ASM
668 __asm __volatile(" \n\
674 "=d" (_port_), "=S" (addr), "=c" (count) :
675 "0" (_port_), "1" (addr), "2" (count) :
676 "%eax", "memory", "cc");
679 bus_space_handle_t _port_ = bsh + offset;
680 #ifdef __GNUCLIKE_ASM
681 __asm __volatile(" \n\
685 "=D" (_port_), "=S" (addr), "=c" (count) :
686 "0" (_port_), "1" (addr), "2" (count) :
693 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
694 bus_size_t offset, const u_int16_t *addr, size_t count)
697 if (tag == X86_BUS_SPACE_IO) {
698 int _port_ = bsh + offset;
699 #ifdef __GNUCLIKE_ASM
700 __asm __volatile(" \n\
706 "=d" (_port_), "=S" (addr), "=c" (count) :
707 "0" (_port_), "1" (addr), "2" (count) :
708 "%eax", "memory", "cc");
711 bus_space_handle_t _port_ = bsh + offset;
712 #ifdef __GNUCLIKE_ASM
713 __asm __volatile(" \n\
717 "=D" (_port_), "=S" (addr), "=c" (count) :
718 "0" (_port_), "1" (addr), "2" (count) :
725 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
726 bus_size_t offset, const u_int32_t *addr, size_t count)
729 if (tag == X86_BUS_SPACE_IO) {
730 int _port_ = bsh + offset;
731 #ifdef __GNUCLIKE_ASM
732 __asm __volatile(" \n\
738 "=d" (_port_), "=S" (addr), "=c" (count) :
739 "0" (_port_), "1" (addr), "2" (count) :
740 "%eax", "memory", "cc");
743 bus_space_handle_t _port_ = bsh + offset;
744 #ifdef __GNUCLIKE_ASM
745 __asm __volatile(" \n\
749 "=D" (_port_), "=S" (addr), "=c" (count) :
750 "0" (_port_), "1" (addr), "2" (count) :
756 #if 0 /* Cause a link error for bus_space_write_region_8 */
757 #define bus_space_write_region_8 \
758 !!! bus_space_write_region_8 unimplemented !!!
762 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
763 * by tag/handle/offset `count' times.
766 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
767 bus_space_handle_t bsh,
769 u_int8_t value, size_t count);
770 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
771 bus_space_handle_t bsh,
773 u_int16_t value, size_t count);
774 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
775 bus_space_handle_t bsh,
777 u_int32_t value, size_t count);
780 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
781 bus_size_t offset, u_int8_t value, size_t count)
783 bus_space_handle_t addr = bsh + offset;
785 if (tag == X86_BUS_SPACE_IO)
790 *(volatile u_int8_t *)(addr) = value;
794 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
795 bus_size_t offset, u_int16_t value, size_t count)
797 bus_space_handle_t addr = bsh + offset;
799 if (tag == X86_BUS_SPACE_IO)
804 *(volatile u_int16_t *)(addr) = value;
808 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
809 bus_size_t offset, u_int32_t value, size_t count)
811 bus_space_handle_t addr = bsh + offset;
813 if (tag == X86_BUS_SPACE_IO)
818 *(volatile u_int32_t *)(addr) = value;
821 #if 0 /* Cause a link error for bus_space_set_multi_8 */
822 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
826 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
827 * by tag/handle starting at `offset'.
830 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
831 bus_space_handle_t bsh,
832 bus_size_t offset, u_int8_t value,
834 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
835 bus_space_handle_t bsh,
836 bus_size_t offset, u_int16_t value,
838 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
839 bus_space_handle_t bsh,
840 bus_size_t offset, u_int32_t value,
844 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
845 bus_size_t offset, u_int8_t value, size_t count)
847 bus_space_handle_t addr = bsh + offset;
849 if (tag == X86_BUS_SPACE_IO)
850 for (; count != 0; count--, addr++)
853 for (; count != 0; count--, addr++)
854 *(volatile u_int8_t *)(addr) = value;
858 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
859 bus_size_t offset, u_int16_t value, size_t count)
861 bus_space_handle_t addr = bsh + offset;
863 if (tag == X86_BUS_SPACE_IO)
864 for (; count != 0; count--, addr += 2)
867 for (; count != 0; count--, addr += 2)
868 *(volatile u_int16_t *)(addr) = value;
872 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
873 bus_size_t offset, u_int32_t value, size_t count)
875 bus_space_handle_t addr = bsh + offset;
877 if (tag == X86_BUS_SPACE_IO)
878 for (; count != 0; count--, addr += 4)
881 for (; count != 0; count--, addr += 4)
882 *(volatile u_int32_t *)(addr) = value;
885 #if 0 /* Cause a link error for bus_space_set_region_8 */
886 #define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
890 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
891 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
894 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
895 bus_space_handle_t bsh1,
897 bus_space_handle_t bsh2,
898 bus_size_t off2, size_t count);
900 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
901 bus_space_handle_t bsh1,
903 bus_space_handle_t bsh2,
904 bus_size_t off2, size_t count);
906 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
907 bus_space_handle_t bsh1,
909 bus_space_handle_t bsh2,
910 bus_size_t off2, size_t count);
913 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
914 bus_size_t off1, bus_space_handle_t bsh2,
915 bus_size_t off2, size_t count)
917 bus_space_handle_t addr1 = bsh1 + off1;
918 bus_space_handle_t addr2 = bsh2 + off2;
920 if (tag == X86_BUS_SPACE_IO) {
921 if (addr1 >= addr2) {
922 /* src after dest: copy forward */
923 for (; count != 0; count--, addr1++, addr2++)
924 outb(addr2, inb(addr1));
926 /* dest after src: copy backwards */
927 for (addr1 += (count - 1), addr2 += (count - 1);
928 count != 0; count--, addr1--, addr2--)
929 outb(addr2, inb(addr1));
932 if (addr1 >= addr2) {
933 /* src after dest: copy forward */
934 for (; count != 0; count--, addr1++, addr2++)
935 *(volatile u_int8_t *)(addr2) =
936 *(volatile u_int8_t *)(addr1);
938 /* dest after src: copy backwards */
939 for (addr1 += (count - 1), addr2 += (count - 1);
940 count != 0; count--, addr1--, addr2--)
941 *(volatile u_int8_t *)(addr2) =
942 *(volatile u_int8_t *)(addr1);
948 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
949 bus_size_t off1, bus_space_handle_t bsh2,
950 bus_size_t off2, size_t count)
952 bus_space_handle_t addr1 = bsh1 + off1;
953 bus_space_handle_t addr2 = bsh2 + off2;
955 if (tag == X86_BUS_SPACE_IO) {
956 if (addr1 >= addr2) {
957 /* src after dest: copy forward */
958 for (; count != 0; count--, addr1 += 2, addr2 += 2)
959 outw(addr2, inw(addr1));
961 /* dest after src: copy backwards */
962 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
963 count != 0; count--, addr1 -= 2, addr2 -= 2)
964 outw(addr2, inw(addr1));
967 if (addr1 >= addr2) {
968 /* src after dest: copy forward */
969 for (; count != 0; count--, addr1 += 2, addr2 += 2)
970 *(volatile u_int16_t *)(addr2) =
971 *(volatile u_int16_t *)(addr1);
973 /* dest after src: copy backwards */
974 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
975 count != 0; count--, addr1 -= 2, addr2 -= 2)
976 *(volatile u_int16_t *)(addr2) =
977 *(volatile u_int16_t *)(addr1);
983 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
984 bus_size_t off1, bus_space_handle_t bsh2,
985 bus_size_t off2, size_t count)
987 bus_space_handle_t addr1 = bsh1 + off1;
988 bus_space_handle_t addr2 = bsh2 + off2;
990 if (tag == X86_BUS_SPACE_IO) {
991 if (addr1 >= addr2) {
992 /* src after dest: copy forward */
993 for (; count != 0; count--, addr1 += 4, addr2 += 4)
994 outl(addr2, inl(addr1));
996 /* dest after src: copy backwards */
997 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
998 count != 0; count--, addr1 -= 4, addr2 -= 4)
999 outl(addr2, inl(addr1));
1002 if (addr1 >= addr2) {
1003 /* src after dest: copy forward */
1004 for (; count != 0; count--, addr1 += 4, addr2 += 4)
1005 *(volatile u_int32_t *)(addr2) =
1006 *(volatile u_int32_t *)(addr1);
1008 /* dest after src: copy backwards */
1009 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1010 count != 0; count--, addr1 -= 4, addr2 -= 4)
1011 *(volatile u_int32_t *)(addr2) =
1012 *(volatile u_int32_t *)(addr1);
1017 #if 0 /* Cause a link error for bus_space_copy_8 */
1018 #define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
1022 * Bus read/write barrier methods.
1024 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
1025 * bus_size_t offset, bus_size_t len, int flags);
1028 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
1029 * prevent reordering by the compiler; all Intel x86 processors currently
1030 * retire operations outside the CPU in program order.
1032 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
1033 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
1035 static __inline void
1036 bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
1037 bus_size_t offset __unused, bus_size_t len __unused, int flags)
1039 #ifdef __GNUCLIKE_ASM
1040 if (flags & BUS_SPACE_BARRIER_READ)
1042 __asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
1044 __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
1047 __compiler_membar();
1051 #ifdef BUS_SPACE_NO_LEGACY
1054 #define inb(a) compiler_error
1055 #define inw(a) compiler_error
1056 #define inl(a) compiler_error
1057 #define outb(a, b) compiler_error
1058 #define outw(a, b) compiler_error
1059 #define outl(a, b) compiler_error
1062 #include <machine/bus_dma.h>
1065 * Stream accesses are the same as normal accesses on x86; there are no
1066 * supported bus systems with an endianess different from the host one.
1068 #define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o))
1069 #define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o))
1070 #define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o))
1072 #define bus_space_read_multi_stream_1(t, h, o, a, c) \
1073 bus_space_read_multi_1((t), (h), (o), (a), (c))
1074 #define bus_space_read_multi_stream_2(t, h, o, a, c) \
1075 bus_space_read_multi_2((t), (h), (o), (a), (c))
1076 #define bus_space_read_multi_stream_4(t, h, o, a, c) \
1077 bus_space_read_multi_4((t), (h), (o), (a), (c))
1079 #define bus_space_write_stream_1(t, h, o, v) \
1080 bus_space_write_1((t), (h), (o), (v))
1081 #define bus_space_write_stream_2(t, h, o, v) \
1082 bus_space_write_2((t), (h), (o), (v))
1083 #define bus_space_write_stream_4(t, h, o, v) \
1084 bus_space_write_4((t), (h), (o), (v))
1086 #define bus_space_write_multi_stream_1(t, h, o, a, c) \
1087 bus_space_write_multi_1((t), (h), (o), (a), (c))
1088 #define bus_space_write_multi_stream_2(t, h, o, a, c) \
1089 bus_space_write_multi_2((t), (h), (o), (a), (c))
1090 #define bus_space_write_multi_stream_4(t, h, o, a, c) \
1091 bus_space_write_multi_4((t), (h), (o), (a), (c))
1093 #define bus_space_set_multi_stream_1(t, h, o, v, c) \
1094 bus_space_set_multi_1((t), (h), (o), (v), (c))
1095 #define bus_space_set_multi_stream_2(t, h, o, v, c) \
1096 bus_space_set_multi_2((t), (h), (o), (v), (c))
1097 #define bus_space_set_multi_stream_4(t, h, o, v, c) \
1098 bus_space_set_multi_4((t), (h), (o), (v), (c))
1100 #define bus_space_read_region_stream_1(t, h, o, a, c) \
1101 bus_space_read_region_1((t), (h), (o), (a), (c))
1102 #define bus_space_read_region_stream_2(t, h, o, a, c) \
1103 bus_space_read_region_2((t), (h), (o), (a), (c))
1104 #define bus_space_read_region_stream_4(t, h, o, a, c) \
1105 bus_space_read_region_4((t), (h), (o), (a), (c))
1107 #define bus_space_write_region_stream_1(t, h, o, a, c) \
1108 bus_space_write_region_1((t), (h), (o), (a), (c))
1109 #define bus_space_write_region_stream_2(t, h, o, a, c) \
1110 bus_space_write_region_2((t), (h), (o), (a), (c))
1111 #define bus_space_write_region_stream_4(t, h, o, a, c) \
1112 bus_space_write_region_4((t), (h), (o), (a), (c))
1114 #define bus_space_set_region_stream_1(t, h, o, v, c) \
1115 bus_space_set_region_1((t), (h), (o), (v), (c))
1116 #define bus_space_set_region_stream_2(t, h, o, v, c) \
1117 bus_space_set_region_2((t), (h), (o), (v), (c))
1118 #define bus_space_set_region_stream_4(t, h, o, v, c) \
1119 bus_space_set_region_4((t), (h), (o), (v), (c))
1121 #define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
1122 bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
1123 #define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
1124 bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
1125 #define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
1126 bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
1128 #endif /* _X86_BUS_H_ */