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.
53 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
54 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
55 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
56 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
57 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
58 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
59 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
60 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
61 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
62 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
63 * POSSIBILITY OF SUCH DAMAGE.
67 * Copyright (c) 1996 Charles M. Hannum. All rights reserved.
68 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
70 * Redistribution and use in source and binary forms, with or without
71 * modification, are permitted provided that the following conditions
73 * 1. Redistributions of source code must retain the above copyright
74 * notice, this list of conditions and the following disclaimer.
75 * 2. Redistributions in binary form must reproduce the above copyright
76 * notice, this list of conditions and the following disclaimer in the
77 * documentation and/or other materials provided with the distribution.
78 * 3. All advertising materials mentioning features or use of this software
79 * must display the following acknowledgement:
80 * This product includes software developed by Christopher G. Demetriou
81 * for the NetBSD Project.
82 * 4. The name of the author may not be used to endorse or promote products
83 * derived from this software without specific prior written permission
85 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
86 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
87 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
88 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
89 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
90 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
91 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
92 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
93 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
94 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
100 #include <machine/_bus.h>
101 #include <machine/cpufunc.h>
103 #ifndef __GNUCLIKE_ASM
105 # error "no assembler code for your compiler"
110 * Values for the x86 bus space tag, not to be used directly by MI code.
112 #define X86_BUS_SPACE_IO 0 /* space is i/o space */
113 #define X86_BUS_SPACE_MEM 1 /* space is mem space */
115 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
116 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
117 #define BUS_SPACE_MAXSIZE 0xFFFFFFFF
118 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
119 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
120 #if defined(__amd64__) || defined(PAE)
121 #define BUS_SPACE_MAXADDR 0xFFFFFFFFFFFFFFFFULL
123 #define BUS_SPACE_MAXADDR 0xFFFFFFFF
126 #define BUS_SPACE_INVALID_DATA (~0)
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,
219 static __inline uint64_t bus_space_read_8(bus_space_tag_t tag,
220 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));
255 static __inline uint64_t
256 bus_space_read_8(bus_space_tag_t tag, bus_space_handle_t handle,
260 if (tag == X86_BUS_SPACE_IO) /* No 8 byte IO space access on x86 */
261 return (BUS_SPACE_INVALID_DATA);
262 return (*(volatile uint64_t *)(handle + offset));
267 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
268 * described by tag/handle/offset and copy into buffer provided.
270 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
271 bus_space_handle_t bsh,
272 bus_size_t offset, u_int8_t *addr,
275 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
276 bus_space_handle_t bsh,
277 bus_size_t offset, u_int16_t *addr,
280 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
281 bus_space_handle_t bsh,
282 bus_size_t offset, u_int32_t *addr,
286 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
287 bus_size_t offset, u_int8_t *addr, size_t count)
290 if (tag == X86_BUS_SPACE_IO)
291 insb(bsh + offset, addr, count);
293 #ifdef __GNUCLIKE_ASM
294 __asm __volatile(" \n\
296 1: movb (%2),%%al \n\
299 "=D" (addr), "=c" (count) :
300 "r" (bsh + offset), "0" (addr), "1" (count) :
307 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
308 bus_size_t offset, u_int16_t *addr, size_t count)
311 if (tag == X86_BUS_SPACE_IO)
312 insw(bsh + offset, addr, count);
314 #ifdef __GNUCLIKE_ASM
315 __asm __volatile(" \n\
317 1: movw (%2),%%ax \n\
320 "=D" (addr), "=c" (count) :
321 "r" (bsh + offset), "0" (addr), "1" (count) :
328 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
329 bus_size_t offset, u_int32_t *addr, size_t count)
332 if (tag == X86_BUS_SPACE_IO)
333 insl(bsh + offset, addr, count);
335 #ifdef __GNUCLIKE_ASM
336 __asm __volatile(" \n\
338 1: movl (%2),%%eax \n\
341 "=D" (addr), "=c" (count) :
342 "r" (bsh + offset), "0" (addr), "1" (count) :
348 #if 0 /* Cause a link error for bus_space_read_multi_8 */
349 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
353 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
354 * described by tag/handle and starting at `offset' and copy into
357 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
358 bus_space_handle_t bsh,
359 bus_size_t offset, u_int8_t *addr,
362 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
363 bus_space_handle_t bsh,
364 bus_size_t offset, u_int16_t *addr,
367 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
368 bus_space_handle_t bsh,
369 bus_size_t offset, u_int32_t *addr,
374 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
375 bus_size_t offset, u_int8_t *addr, size_t count)
378 if (tag == X86_BUS_SPACE_IO) {
379 int _port_ = bsh + offset;
380 #ifdef __GNUCLIKE_ASM
381 __asm __volatile(" \n\
387 "=D" (addr), "=c" (count), "=d" (_port_) :
388 "0" (addr), "1" (count), "2" (_port_) :
389 "%eax", "memory", "cc");
392 bus_space_handle_t _port_ = bsh + offset;
393 #ifdef __GNUCLIKE_ASM
394 __asm __volatile(" \n\
398 "=D" (addr), "=c" (count), "=S" (_port_) :
399 "0" (addr), "1" (count), "2" (_port_) :
406 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
407 bus_size_t offset, u_int16_t *addr, size_t count)
410 if (tag == X86_BUS_SPACE_IO) {
411 int _port_ = bsh + offset;
412 #ifdef __GNUCLIKE_ASM
413 __asm __volatile(" \n\
419 "=D" (addr), "=c" (count), "=d" (_port_) :
420 "0" (addr), "1" (count), "2" (_port_) :
421 "%eax", "memory", "cc");
424 bus_space_handle_t _port_ = bsh + offset;
425 #ifdef __GNUCLIKE_ASM
426 __asm __volatile(" \n\
430 "=D" (addr), "=c" (count), "=S" (_port_) :
431 "0" (addr), "1" (count), "2" (_port_) :
438 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
439 bus_size_t offset, u_int32_t *addr, size_t count)
442 if (tag == X86_BUS_SPACE_IO) {
443 int _port_ = bsh + offset;
444 #ifdef __GNUCLIKE_ASM
445 __asm __volatile(" \n\
451 "=D" (addr), "=c" (count), "=d" (_port_) :
452 "0" (addr), "1" (count), "2" (_port_) :
453 "%eax", "memory", "cc");
456 bus_space_handle_t _port_ = bsh + offset;
457 #ifdef __GNUCLIKE_ASM
458 __asm __volatile(" \n\
462 "=D" (addr), "=c" (count), "=S" (_port_) :
463 "0" (addr), "1" (count), "2" (_port_) :
469 #if 0 /* Cause a link error for bus_space_read_region_8 */
470 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
474 * Write the 1, 2, 4, or 8 byte value `value' to bus space
475 * described by tag/handle/offset.
478 static __inline void bus_space_write_1(bus_space_tag_t tag,
479 bus_space_handle_t bsh,
480 bus_size_t offset, u_int8_t value);
482 static __inline void bus_space_write_2(bus_space_tag_t tag,
483 bus_space_handle_t bsh,
484 bus_size_t offset, u_int16_t value);
486 static __inline void bus_space_write_4(bus_space_tag_t tag,
487 bus_space_handle_t bsh,
488 bus_size_t offset, u_int32_t value);
491 static __inline void bus_space_write_8(bus_space_tag_t tag,
492 bus_space_handle_t bsh,
493 bus_size_t offset, uint64_t value);
497 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
498 bus_size_t offset, u_int8_t value)
501 if (tag == X86_BUS_SPACE_IO)
502 outb(bsh + offset, value);
504 *(volatile u_int8_t *)(bsh + offset) = value;
508 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
509 bus_size_t offset, u_int16_t value)
512 if (tag == X86_BUS_SPACE_IO)
513 outw(bsh + offset, value);
515 *(volatile u_int16_t *)(bsh + offset) = value;
519 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
520 bus_size_t offset, u_int32_t value)
523 if (tag == X86_BUS_SPACE_IO)
524 outl(bsh + offset, value);
526 *(volatile u_int32_t *)(bsh + offset) = value;
531 bus_space_write_8(bus_space_tag_t tag, bus_space_handle_t bsh,
532 bus_size_t offset, uint64_t value)
535 if (tag == X86_BUS_SPACE_IO) /* No 8 byte IO space access on x86 */
538 *(volatile uint64_t *)(bsh + offset) = value;
543 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
544 * provided to bus space described by tag/handle/offset.
547 static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
548 bus_space_handle_t bsh,
550 const u_int8_t *addr,
552 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
553 bus_space_handle_t bsh,
555 const u_int16_t *addr,
558 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
559 bus_space_handle_t bsh,
561 const u_int32_t *addr,
565 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
566 bus_size_t offset, const u_int8_t *addr, size_t count)
569 if (tag == X86_BUS_SPACE_IO)
570 outsb(bsh + offset, addr, count);
572 #ifdef __GNUCLIKE_ASM
573 __asm __volatile(" \n\
578 "=S" (addr), "=c" (count) :
579 "r" (bsh + offset), "0" (addr), "1" (count) :
580 "%eax", "memory", "cc");
586 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
587 bus_size_t offset, const u_int16_t *addr, size_t count)
590 if (tag == X86_BUS_SPACE_IO)
591 outsw(bsh + offset, addr, count);
593 #ifdef __GNUCLIKE_ASM
594 __asm __volatile(" \n\
599 "=S" (addr), "=c" (count) :
600 "r" (bsh + offset), "0" (addr), "1" (count) :
601 "%eax", "memory", "cc");
607 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
608 bus_size_t offset, const u_int32_t *addr, size_t count)
611 if (tag == X86_BUS_SPACE_IO)
612 outsl(bsh + offset, addr, count);
614 #ifdef __GNUCLIKE_ASM
615 __asm __volatile(" \n\
620 "=S" (addr), "=c" (count) :
621 "r" (bsh + offset), "0" (addr), "1" (count) :
622 "%eax", "memory", "cc");
627 #if 0 /* Cause a link error for bus_space_write_multi_8 */
628 #define bus_space_write_multi_8(t, h, o, a, c) \
629 !!! bus_space_write_multi_8 unimplemented !!!
633 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
634 * to bus space described by tag/handle starting at `offset'.
637 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
638 bus_space_handle_t bsh,
640 const u_int8_t *addr,
642 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
643 bus_space_handle_t bsh,
645 const u_int16_t *addr,
647 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
648 bus_space_handle_t bsh,
650 const u_int32_t *addr,
654 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
655 bus_size_t offset, const u_int8_t *addr, size_t count)
658 if (tag == X86_BUS_SPACE_IO) {
659 int _port_ = bsh + offset;
660 #ifdef __GNUCLIKE_ASM
661 __asm __volatile(" \n\
667 "=d" (_port_), "=S" (addr), "=c" (count) :
668 "0" (_port_), "1" (addr), "2" (count) :
669 "%eax", "memory", "cc");
672 bus_space_handle_t _port_ = bsh + offset;
673 #ifdef __GNUCLIKE_ASM
674 __asm __volatile(" \n\
678 "=D" (_port_), "=S" (addr), "=c" (count) :
679 "0" (_port_), "1" (addr), "2" (count) :
686 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
687 bus_size_t offset, const u_int16_t *addr, size_t count)
690 if (tag == X86_BUS_SPACE_IO) {
691 int _port_ = bsh + offset;
692 #ifdef __GNUCLIKE_ASM
693 __asm __volatile(" \n\
699 "=d" (_port_), "=S" (addr), "=c" (count) :
700 "0" (_port_), "1" (addr), "2" (count) :
701 "%eax", "memory", "cc");
704 bus_space_handle_t _port_ = bsh + offset;
705 #ifdef __GNUCLIKE_ASM
706 __asm __volatile(" \n\
710 "=D" (_port_), "=S" (addr), "=c" (count) :
711 "0" (_port_), "1" (addr), "2" (count) :
718 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
719 bus_size_t offset, const u_int32_t *addr, size_t count)
722 if (tag == X86_BUS_SPACE_IO) {
723 int _port_ = bsh + offset;
724 #ifdef __GNUCLIKE_ASM
725 __asm __volatile(" \n\
731 "=d" (_port_), "=S" (addr), "=c" (count) :
732 "0" (_port_), "1" (addr), "2" (count) :
733 "%eax", "memory", "cc");
736 bus_space_handle_t _port_ = bsh + offset;
737 #ifdef __GNUCLIKE_ASM
738 __asm __volatile(" \n\
742 "=D" (_port_), "=S" (addr), "=c" (count) :
743 "0" (_port_), "1" (addr), "2" (count) :
749 #if 0 /* Cause a link error for bus_space_write_region_8 */
750 #define bus_space_write_region_8 \
751 !!! bus_space_write_region_8 unimplemented !!!
755 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
756 * by tag/handle/offset `count' times.
759 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
760 bus_space_handle_t bsh,
762 u_int8_t value, size_t count);
763 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
764 bus_space_handle_t bsh,
766 u_int16_t value, size_t count);
767 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
768 bus_space_handle_t bsh,
770 u_int32_t value, size_t count);
773 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
774 bus_size_t offset, u_int8_t value, size_t count)
776 bus_space_handle_t addr = bsh + offset;
778 if (tag == X86_BUS_SPACE_IO)
783 *(volatile u_int8_t *)(addr) = value;
787 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
788 bus_size_t offset, u_int16_t value, size_t count)
790 bus_space_handle_t addr = bsh + offset;
792 if (tag == X86_BUS_SPACE_IO)
797 *(volatile u_int16_t *)(addr) = value;
801 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
802 bus_size_t offset, u_int32_t value, size_t count)
804 bus_space_handle_t addr = bsh + offset;
806 if (tag == X86_BUS_SPACE_IO)
811 *(volatile u_int32_t *)(addr) = value;
814 #if 0 /* Cause a link error for bus_space_set_multi_8 */
815 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
819 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
820 * by tag/handle starting at `offset'.
823 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
824 bus_space_handle_t bsh,
825 bus_size_t offset, u_int8_t value,
827 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
828 bus_space_handle_t bsh,
829 bus_size_t offset, u_int16_t value,
831 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
832 bus_space_handle_t bsh,
833 bus_size_t offset, u_int32_t value,
837 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
838 bus_size_t offset, u_int8_t value, size_t count)
840 bus_space_handle_t addr = bsh + offset;
842 if (tag == X86_BUS_SPACE_IO)
843 for (; count != 0; count--, addr++)
846 for (; count != 0; count--, addr++)
847 *(volatile u_int8_t *)(addr) = value;
851 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
852 bus_size_t offset, u_int16_t value, size_t count)
854 bus_space_handle_t addr = bsh + offset;
856 if (tag == X86_BUS_SPACE_IO)
857 for (; count != 0; count--, addr += 2)
860 for (; count != 0; count--, addr += 2)
861 *(volatile u_int16_t *)(addr) = value;
865 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
866 bus_size_t offset, u_int32_t value, size_t count)
868 bus_space_handle_t addr = bsh + offset;
870 if (tag == X86_BUS_SPACE_IO)
871 for (; count != 0; count--, addr += 4)
874 for (; count != 0; count--, addr += 4)
875 *(volatile u_int32_t *)(addr) = value;
878 #if 0 /* Cause a link error for bus_space_set_region_8 */
879 #define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
883 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
884 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
887 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
888 bus_space_handle_t bsh1,
890 bus_space_handle_t bsh2,
891 bus_size_t off2, size_t count);
893 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
894 bus_space_handle_t bsh1,
896 bus_space_handle_t bsh2,
897 bus_size_t off2, size_t count);
899 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
900 bus_space_handle_t bsh1,
902 bus_space_handle_t bsh2,
903 bus_size_t off2, size_t count);
906 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
907 bus_size_t off1, bus_space_handle_t bsh2,
908 bus_size_t off2, size_t count)
910 bus_space_handle_t addr1 = bsh1 + off1;
911 bus_space_handle_t addr2 = bsh2 + off2;
913 if (tag == X86_BUS_SPACE_IO) {
914 if (addr1 >= addr2) {
915 /* src after dest: copy forward */
916 for (; count != 0; count--, addr1++, addr2++)
917 outb(addr2, inb(addr1));
919 /* dest after src: copy backwards */
920 for (addr1 += (count - 1), addr2 += (count - 1);
921 count != 0; count--, addr1--, addr2--)
922 outb(addr2, inb(addr1));
925 if (addr1 >= addr2) {
926 /* src after dest: copy forward */
927 for (; count != 0; count--, addr1++, addr2++)
928 *(volatile u_int8_t *)(addr2) =
929 *(volatile u_int8_t *)(addr1);
931 /* dest after src: copy backwards */
932 for (addr1 += (count - 1), addr2 += (count - 1);
933 count != 0; count--, addr1--, addr2--)
934 *(volatile u_int8_t *)(addr2) =
935 *(volatile u_int8_t *)(addr1);
941 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
942 bus_size_t off1, bus_space_handle_t bsh2,
943 bus_size_t off2, size_t count)
945 bus_space_handle_t addr1 = bsh1 + off1;
946 bus_space_handle_t addr2 = bsh2 + off2;
948 if (tag == X86_BUS_SPACE_IO) {
949 if (addr1 >= addr2) {
950 /* src after dest: copy forward */
951 for (; count != 0; count--, addr1 += 2, addr2 += 2)
952 outw(addr2, inw(addr1));
954 /* dest after src: copy backwards */
955 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
956 count != 0; count--, addr1 -= 2, addr2 -= 2)
957 outw(addr2, inw(addr1));
960 if (addr1 >= addr2) {
961 /* src after dest: copy forward */
962 for (; count != 0; count--, addr1 += 2, addr2 += 2)
963 *(volatile u_int16_t *)(addr2) =
964 *(volatile u_int16_t *)(addr1);
966 /* dest after src: copy backwards */
967 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
968 count != 0; count--, addr1 -= 2, addr2 -= 2)
969 *(volatile u_int16_t *)(addr2) =
970 *(volatile u_int16_t *)(addr1);
976 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
977 bus_size_t off1, bus_space_handle_t bsh2,
978 bus_size_t off2, size_t count)
980 bus_space_handle_t addr1 = bsh1 + off1;
981 bus_space_handle_t addr2 = bsh2 + off2;
983 if (tag == X86_BUS_SPACE_IO) {
984 if (addr1 >= addr2) {
985 /* src after dest: copy forward */
986 for (; count != 0; count--, addr1 += 4, addr2 += 4)
987 outl(addr2, inl(addr1));
989 /* dest after src: copy backwards */
990 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
991 count != 0; count--, addr1 -= 4, addr2 -= 4)
992 outl(addr2, inl(addr1));
995 if (addr1 >= addr2) {
996 /* src after dest: copy forward */
997 for (; count != 0; count--, addr1 += 4, addr2 += 4)
998 *(volatile u_int32_t *)(addr2) =
999 *(volatile u_int32_t *)(addr1);
1001 /* dest after src: copy backwards */
1002 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1003 count != 0; count--, addr1 -= 4, addr2 -= 4)
1004 *(volatile u_int32_t *)(addr2) =
1005 *(volatile u_int32_t *)(addr1);
1010 #if 0 /* Cause a link error for bus_space_copy_8 */
1011 #define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
1015 * Bus read/write barrier methods.
1017 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
1018 * bus_size_t offset, bus_size_t len, int flags);
1021 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
1022 * prevent reordering by the compiler; all Intel x86 processors currently
1023 * retire operations outside the CPU in program order.
1025 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
1026 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
1028 static __inline void
1029 bus_space_barrier(bus_space_tag_t tag __unused, bus_space_handle_t bsh __unused,
1030 bus_size_t offset __unused, bus_size_t len __unused, int flags)
1032 #ifdef __GNUCLIKE_ASM
1033 if (flags & BUS_SPACE_BARRIER_READ)
1035 __asm __volatile("lock; addl $0,0(%%rsp)" : : : "memory");
1037 __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
1040 __compiler_membar();
1044 #ifdef BUS_SPACE_NO_LEGACY
1047 #define inb(a) compiler_error
1048 #define inw(a) compiler_error
1049 #define inl(a) compiler_error
1050 #define outb(a, b) compiler_error
1051 #define outw(a, b) compiler_error
1052 #define outl(a, b) compiler_error
1055 #include <machine/bus_dma.h>
1058 * Stream accesses are the same as normal accesses on x86; there are no
1059 * supported bus systems with an endianess different from the host one.
1061 #define bus_space_read_stream_1(t, h, o) bus_space_read_1((t), (h), (o))
1062 #define bus_space_read_stream_2(t, h, o) bus_space_read_2((t), (h), (o))
1063 #define bus_space_read_stream_4(t, h, o) bus_space_read_4((t), (h), (o))
1065 #define bus_space_read_multi_stream_1(t, h, o, a, c) \
1066 bus_space_read_multi_1((t), (h), (o), (a), (c))
1067 #define bus_space_read_multi_stream_2(t, h, o, a, c) \
1068 bus_space_read_multi_2((t), (h), (o), (a), (c))
1069 #define bus_space_read_multi_stream_4(t, h, o, a, c) \
1070 bus_space_read_multi_4((t), (h), (o), (a), (c))
1072 #define bus_space_write_stream_1(t, h, o, v) \
1073 bus_space_write_1((t), (h), (o), (v))
1074 #define bus_space_write_stream_2(t, h, o, v) \
1075 bus_space_write_2((t), (h), (o), (v))
1076 #define bus_space_write_stream_4(t, h, o, v) \
1077 bus_space_write_4((t), (h), (o), (v))
1079 #define bus_space_write_multi_stream_1(t, h, o, a, c) \
1080 bus_space_write_multi_1((t), (h), (o), (a), (c))
1081 #define bus_space_write_multi_stream_2(t, h, o, a, c) \
1082 bus_space_write_multi_2((t), (h), (o), (a), (c))
1083 #define bus_space_write_multi_stream_4(t, h, o, a, c) \
1084 bus_space_write_multi_4((t), (h), (o), (a), (c))
1086 #define bus_space_set_multi_stream_1(t, h, o, v, c) \
1087 bus_space_set_multi_1((t), (h), (o), (v), (c))
1088 #define bus_space_set_multi_stream_2(t, h, o, v, c) \
1089 bus_space_set_multi_2((t), (h), (o), (v), (c))
1090 #define bus_space_set_multi_stream_4(t, h, o, v, c) \
1091 bus_space_set_multi_4((t), (h), (o), (v), (c))
1093 #define bus_space_read_region_stream_1(t, h, o, a, c) \
1094 bus_space_read_region_1((t), (h), (o), (a), (c))
1095 #define bus_space_read_region_stream_2(t, h, o, a, c) \
1096 bus_space_read_region_2((t), (h), (o), (a), (c))
1097 #define bus_space_read_region_stream_4(t, h, o, a, c) \
1098 bus_space_read_region_4((t), (h), (o), (a), (c))
1100 #define bus_space_write_region_stream_1(t, h, o, a, c) \
1101 bus_space_write_region_1((t), (h), (o), (a), (c))
1102 #define bus_space_write_region_stream_2(t, h, o, a, c) \
1103 bus_space_write_region_2((t), (h), (o), (a), (c))
1104 #define bus_space_write_region_stream_4(t, h, o, a, c) \
1105 bus_space_write_region_4((t), (h), (o), (a), (c))
1107 #define bus_space_set_region_stream_1(t, h, o, v, c) \
1108 bus_space_set_region_1((t), (h), (o), (v), (c))
1109 #define bus_space_set_region_stream_2(t, h, o, v, c) \
1110 bus_space_set_region_2((t), (h), (o), (v), (c))
1111 #define bus_space_set_region_stream_4(t, h, o, v, c) \
1112 bus_space_set_region_4((t), (h), (o), (v), (c))
1114 #define bus_space_copy_region_stream_1(t, h1, o1, h2, o2, c) \
1115 bus_space_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
1116 #define bus_space_copy_region_stream_2(t, h1, o1, h2, o2, c) \
1117 bus_space_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
1118 #define bus_space_copy_region_stream_4(t, h1, o1, h2, o2, c) \
1119 bus_space_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
1121 #endif /* _X86_BUS_H_ */