1 /* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the NetBSD
22 * Foundation, Inc. and its contributors.
23 * 4. Neither the name of The NetBSD Foundation nor the names of its
24 * contributors may be used to endorse or promote products derived
25 * from this software without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
41 * Copyright (c) 1996 Charles M. Hannum. All rights reserved.
42 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
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 Christopher G. Demetriou
55 * for the NetBSD Project.
56 * 4. The name of the author may not be used to endorse or promote products
57 * derived from this software without specific prior written permission
59 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
60 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
61 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
62 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
63 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
64 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
65 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
66 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
67 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
68 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72 #ifndef _I386_BUS_AT386_H_
73 #define _I386_BUS_AT386_H_
75 #include <machine/cpufunc.h>
78 * To remain compatible with NetBSD's interface, default to both memio and
79 * pio when neither of them is defined.
81 #if !defined(_I386_BUS_PIO_H_) && !defined(_I386_BUS_MEMIO_H_)
82 #define _I386_BUS_PIO_H_
83 #define _I386_BUS_MEMIO_H_
87 * Values for the i386 bus space tag, not to be used directly by MI code.
89 #define I386_BUS_SPACE_IO 0 /* space is i/o space */
90 #define I386_BUS_SPACE_MEM 1 /* space is mem space */
93 * Bus address and size types
95 typedef u_int bus_addr_t;
96 typedef u_int bus_size_t;
98 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
99 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
100 #define BUS_SPACE_MAXSIZE (64 * 1024) /* Maximum supported size */
101 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
102 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
103 #define BUS_SPACE_MAXADDR 0xFFFFFFFF
105 #define BUS_SPACE_UNRESTRICTED (~0)
108 * Access methods for bus resources and address space.
110 typedef int bus_space_tag_t;
111 typedef u_int bus_space_handle_t;
114 * Map a region of device bus space into CPU virtual address space.
117 #define BUS_SPACE_MAP_CACHEABLE 0x01
118 #define BUS_SPACE_MAP_LINEAR 0x02
120 int bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
121 int flags, bus_space_handle_t *bshp);
124 * Unmap a region of device bus space.
127 void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
131 * Get a new handle for a subregion of an already-mapped area of bus space.
134 int bus_space_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
135 bus_size_t offset, bus_size_t size,
136 bus_space_handle_t *nbshp);
139 * Allocate a region of memory that is accessible to devices in bus space.
142 int bus_space_alloc(bus_space_tag_t t, bus_addr_t rstart,
143 bus_addr_t rend, bus_size_t size, bus_size_t align,
144 bus_size_t boundary, int flags, bus_addr_t *addrp,
145 bus_space_handle_t *bshp);
148 * Free a region of bus space accessible memory.
151 void bus_space_free(bus_space_tag_t t, bus_space_handle_t bsh,
154 #if defined(_I386_BUS_PIO_H_) || defined(_I386_BUS_MEMIO_H_)
157 * Read a 1, 2, 4, or 8 byte quantity from bus space
158 * described by tag/handle/offset.
160 static __inline u_int8_t bus_space_read_1(bus_space_tag_t tag,
161 bus_space_handle_t handle,
164 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
165 bus_space_handle_t handle,
168 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
169 bus_space_handle_t handle,
172 static __inline u_int8_t
173 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
176 #if defined (_I386_BUS_PIO_H_)
177 #if defined (_I386_BUS_MEMIO_H_)
178 if (tag == I386_BUS_SPACE_IO)
180 return (inb(handle + offset));
182 #if defined (_I386_BUS_MEMIO_H_)
183 return (*(volatile u_int8_t *)(handle + offset));
187 static __inline u_int16_t
188 bus_space_read_2(bus_space_tag_t tag, bus_space_handle_t handle,
191 #if defined(_I386_BUS_PIO_H_)
192 #if defined(_I386_BUS_MEMIO_H_)
193 if (tag == I386_BUS_SPACE_IO)
195 return (inw(handle + offset));
197 #if defined(_I386_BUS_MEMIO_H_)
198 return (*(volatile u_int16_t *)(handle + offset));
202 static __inline u_int32_t
203 bus_space_read_4(bus_space_tag_t tag, bus_space_handle_t handle,
206 #if defined(_I386_BUS_PIO_H_)
207 #if defined(_I386_BUS_MEMIO_H_)
208 if (tag == I386_BUS_SPACE_IO)
210 return (inl(handle + offset));
212 #if defined(_I386_BUS_MEMIO_H_)
213 return (*(volatile u_int32_t *)(handle + offset));
217 #if 0 /* Cause a link error for bus_space_read_8 */
218 #define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
222 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
223 * described by tag/handle/offset and copy into buffer provided.
225 static __inline void bus_space_read_multi_1(bus_space_tag_t tag,
226 bus_space_handle_t bsh,
227 bus_size_t offset, u_int8_t *addr,
230 static __inline void bus_space_read_multi_2(bus_space_tag_t tag,
231 bus_space_handle_t bsh,
232 bus_size_t offset, u_int16_t *addr,
235 static __inline void bus_space_read_multi_4(bus_space_tag_t tag,
236 bus_space_handle_t bsh,
237 bus_size_t offset, u_int32_t *addr,
241 bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
242 bus_size_t offset, u_int8_t *addr, size_t count)
244 #if defined(_I386_BUS_PIO_H_)
245 #if defined(_I386_BUS_MEMIO_H_)
246 if (tag == I386_BUS_SPACE_IO)
248 insb(bsh + offset, addr, count);
250 #if defined(_I386_BUS_MEMIO_H_)
251 #if defined(_I386_BUS_PIO_H_)
255 __asm __volatile(" \n\
257 1: movb (%2),%%al \n\
260 "=D" (addr), "=c" (count) :
261 "r" (bsh + offset), "0" (addr), "1" (count) :
268 bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
269 bus_size_t offset, u_int16_t *addr, size_t count)
271 #if defined(_I386_BUS_PIO_H_)
272 #if defined(_I386_BUS_MEMIO_H_)
273 if (tag == I386_BUS_SPACE_IO)
275 insw(bsh + offset, addr, count);
277 #if defined(_I386_BUS_MEMIO_H_)
278 #if defined(_I386_BUS_PIO_H_)
282 __asm __volatile(" \n\
284 1: movw (%2),%%ax \n\
287 "=D" (addr), "=c" (count) :
288 "r" (bsh + offset), "0" (addr), "1" (count) :
295 bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
296 bus_size_t offset, u_int32_t *addr, size_t count)
298 #if defined(_I386_BUS_PIO_H_)
299 #if defined(_I386_BUS_MEMIO_H_)
300 if (tag == I386_BUS_SPACE_IO)
302 insl(bsh + offset, addr, count);
304 #if defined(_I386_BUS_MEMIO_H_)
305 #if defined(_I386_BUS_PIO_H_)
309 __asm __volatile(" \n\
311 1: movl (%2),%%eax \n\
314 "=D" (addr), "=c" (count) :
315 "r" (bsh + offset), "0" (addr), "1" (count) :
321 #if 0 /* Cause a link error for bus_space_read_multi_8 */
322 #define bus_space_read_multi_8 !!! bus_space_read_multi_8 unimplemented !!!
326 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
327 * described by tag/handle and starting at `offset' and copy into
330 static __inline void bus_space_read_region_1(bus_space_tag_t tag,
331 bus_space_handle_t bsh,
332 bus_size_t offset, u_int8_t *addr,
335 static __inline void bus_space_read_region_2(bus_space_tag_t tag,
336 bus_space_handle_t bsh,
337 bus_size_t offset, u_int16_t *addr,
340 static __inline void bus_space_read_region_4(bus_space_tag_t tag,
341 bus_space_handle_t bsh,
342 bus_size_t offset, u_int32_t *addr,
347 bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
348 bus_size_t offset, u_int8_t *addr, size_t count)
350 #if defined(_I386_BUS_PIO_H_)
351 #if defined(_I386_BUS_MEMIO_H_)
352 if (tag == I386_BUS_SPACE_IO)
355 int _port_ = bsh + offset; \
356 __asm __volatile(" \n\
362 "=D" (addr), "=c" (count), "=d" (_port_) :
363 "0" (addr), "1" (count), "2" (_port_) :
364 "%eax", "memory", "cc");
367 #if defined(_I386_BUS_MEMIO_H_)
368 #if defined(_I386_BUS_PIO_H_)
372 int _port_ = bsh + offset; \
373 __asm __volatile(" \n\
377 "=D" (addr), "=c" (count), "=S" (_port_) :
378 "0" (addr), "1" (count), "2" (_port_) :
385 bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
386 bus_size_t offset, u_int16_t *addr, size_t count)
388 #if defined(_I386_BUS_PIO_H_)
389 #if defined(_I386_BUS_MEMIO_H_)
390 if (tag == I386_BUS_SPACE_IO)
393 int _port_ = bsh + offset; \
394 __asm __volatile(" \n\
400 "=D" (addr), "=c" (count), "=d" (_port_) :
401 "0" (addr), "1" (count), "2" (_port_) :
402 "%eax", "memory", "cc");
405 #if defined(_I386_BUS_MEMIO_H_)
406 #if defined(_I386_BUS_PIO_H_)
410 int _port_ = bsh + offset; \
411 __asm __volatile(" \n\
415 "=D" (addr), "=c" (count), "=S" (_port_) :
416 "0" (addr), "1" (count), "2" (_port_) :
423 bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
424 bus_size_t offset, u_int32_t *addr, size_t count)
426 #if defined(_I386_BUS_PIO_H_)
427 #if defined(_I386_BUS_MEMIO_H_)
428 if (tag == I386_BUS_SPACE_IO)
431 int _port_ = bsh + offset; \
432 __asm __volatile(" \n\
438 "=D" (addr), "=c" (count), "=d" (_port_) :
439 "0" (addr), "1" (count), "2" (_port_) :
440 "%eax", "memory", "cc");
443 #if defined(_I386_BUS_MEMIO_H_)
444 #if defined(_I386_BUS_PIO_H_)
448 int _port_ = bsh + offset; \
449 __asm __volatile(" \n\
453 "=D" (addr), "=c" (count), "=S" (_port_) :
454 "0" (addr), "1" (count), "2" (_port_) :
460 #if 0 /* Cause a link error for bus_space_read_region_8 */
461 #define bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
465 * Write the 1, 2, 4, or 8 byte value `value' to bus space
466 * described by tag/handle/offset.
469 static __inline void bus_space_write_1(bus_space_tag_t tag,
470 bus_space_handle_t bsh,
471 bus_size_t offset, u_int8_t value);
473 static __inline void bus_space_write_2(bus_space_tag_t tag,
474 bus_space_handle_t bsh,
475 bus_size_t offset, u_int16_t value);
477 static __inline void bus_space_write_4(bus_space_tag_t tag,
478 bus_space_handle_t bsh,
479 bus_size_t offset, u_int32_t value);
482 bus_space_write_1(bus_space_tag_t tag, bus_space_handle_t bsh,
483 bus_size_t offset, u_int8_t value)
485 #if defined(_I386_BUS_PIO_H_)
486 #if defined(_I386_BUS_MEMIO_H_)
487 if (tag == I386_BUS_SPACE_IO)
489 outb(bsh + offset, value);
491 #if defined(_I386_BUS_MEMIO_H_)
492 #if defined(_I386_BUS_PIO_H_)
495 *(volatile u_int8_t *)(bsh + offset) = value;
500 bus_space_write_2(bus_space_tag_t tag, bus_space_handle_t bsh,
501 bus_size_t offset, u_int16_t value)
503 #if defined(_I386_BUS_PIO_H_)
504 #if defined(_I386_BUS_MEMIO_H_)
505 if (tag == I386_BUS_SPACE_IO)
507 outw(bsh + offset, value);
509 #if defined(_I386_BUS_MEMIO_H_)
510 #if defined(_I386_BUS_PIO_H_)
513 *(volatile u_int16_t *)(bsh + offset) = value;
518 bus_space_write_4(bus_space_tag_t tag, bus_space_handle_t bsh,
519 bus_size_t offset, u_int32_t value)
521 #if defined(_I386_BUS_PIO_H_)
522 #if defined(_I386_BUS_MEMIO_H_)
523 if (tag == I386_BUS_SPACE_IO)
525 outl(bsh + offset, value);
527 #if defined(_I386_BUS_MEMIO_H_)
528 #if defined(_I386_BUS_PIO_H_)
531 *(volatile u_int32_t *)(bsh + offset) = value;
535 #if 0 /* Cause a link error for bus_space_write_8 */
536 #define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
540 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
541 * provided to bus space described by tag/handle/offset.
544 static __inline void bus_space_write_multi_1(bus_space_tag_t tag,
545 bus_space_handle_t bsh,
547 const u_int8_t *addr,
549 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
550 bus_space_handle_t bsh,
552 const u_int16_t *addr,
555 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
556 bus_space_handle_t bsh,
558 const u_int32_t *addr,
562 bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
563 bus_size_t offset, const u_int8_t *addr, size_t count)
565 #if defined(_I386_BUS_PIO_H_)
566 #if defined(_I386_BUS_MEMIO_H_)
567 if (tag == I386_BUS_SPACE_IO)
569 outsb(bsh + offset, addr, count);
571 #if defined(_I386_BUS_MEMIO_H_)
572 #if defined(_I386_BUS_PIO_H_)
576 __asm __volatile(" \n\
581 "=S" (addr), "=c" (count) :
582 "r" (bsh + offset), "0" (addr), "1" (count) :
583 "%eax", "memory", "cc");
589 bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
590 bus_size_t offset, const u_int16_t *addr, size_t count)
592 #if defined(_I386_BUS_PIO_H_)
593 #if defined(_I386_BUS_MEMIO_H_)
594 if (tag == I386_BUS_SPACE_IO)
596 outsw(bsh + offset, addr, count);
598 #if defined(_I386_BUS_MEMIO_H_)
599 #if defined(_I386_BUS_PIO_H_)
603 __asm __volatile(" \n\
609 "=S" (addr), "=c" (count) :
610 "r" (bsh + offset), "0" (addr), "1" (count) :
611 "%eax", "memory", "cc");
617 bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
618 bus_size_t offset, const u_int32_t *addr, size_t count)
620 #if defined(_I386_BUS_PIO_H_)
621 #if defined(_I386_BUS_MEMIO_H_)
622 if (tag == I386_BUS_SPACE_IO)
624 outsl(bsh + offset, addr, count);
626 #if defined(_I386_BUS_MEMIO_H_)
627 #if defined(_I386_BUS_PIO_H_)
631 __asm __volatile(" \n\
636 "=S" (addr), "=c" (count) :
637 "r" (bsh + offset), "0" (addr), "1" (count) :
638 "%eax", "memory", "cc");
643 #if 0 /* Cause a link error for bus_space_write_multi_8 */
644 #define bus_space_write_multi_8(t, h, o, a, c) \
645 !!! bus_space_write_multi_8 unimplemented !!!
649 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
650 * to bus space described by tag/handle starting at `offset'.
653 static __inline void bus_space_write_region_1(bus_space_tag_t tag,
654 bus_space_handle_t bsh,
656 const u_int8_t *addr,
658 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
659 bus_space_handle_t bsh,
661 const u_int16_t *addr,
663 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
664 bus_space_handle_t bsh,
666 const u_int32_t *addr,
670 bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
671 bus_size_t offset, const u_int8_t *addr, size_t count)
673 #if defined(_I386_BUS_PIO_H_)
674 #if defined(_I386_BUS_MEMIO_H_)
675 if (tag == I386_BUS_SPACE_IO)
678 int _port_ = bsh + offset; \
679 __asm __volatile(" \n\
685 "=d" (_port_), "=S" (addr), "=c" (count) :
686 "0" (_port_), "1" (addr), "2" (count) :
687 "%eax", "memory", "cc");
690 #if defined(_I386_BUS_MEMIO_H_)
691 #if defined(_I386_BUS_PIO_H_)
695 int _port_ = bsh + offset; \
696 __asm __volatile(" \n\
700 "=D" (_port_), "=S" (addr), "=c" (count) :
701 "0" (_port_), "1" (addr), "2" (count) :
708 bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
709 bus_size_t offset, const u_int16_t *addr, size_t count)
711 #if defined(_I386_BUS_PIO_H_)
712 #if defined(_I386_BUS_MEMIO_H_)
713 if (tag == I386_BUS_SPACE_IO)
716 int _port_ = bsh + offset; \
717 __asm __volatile(" \n\
723 "=d" (_port_), "=S" (addr), "=c" (count) :
724 "0" (_port_), "1" (addr), "2" (count) :
725 "%eax", "memory", "cc");
728 #if defined(_I386_BUS_MEMIO_H_)
729 #if defined(_I386_BUS_PIO_H_)
733 int _port_ = bsh + offset; \
734 __asm __volatile(" \n\
738 "=D" (_port_), "=S" (addr), "=c" (count) :
739 "0" (_port_), "1" (addr), "2" (count) :
746 bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
747 bus_size_t offset, const u_int32_t *addr, size_t count)
749 #if defined(_I386_BUS_PIO_H_)
750 #if defined(_I386_BUS_MEMIO_H_)
751 if (tag == I386_BUS_SPACE_IO)
754 int _port_ = bsh + offset; \
755 __asm __volatile(" \n\
761 "=d" (_port_), "=S" (addr), "=c" (count) :
762 "0" (_port_), "1" (addr), "2" (count) :
763 "%eax", "memory", "cc");
766 #if defined(_I386_BUS_MEMIO_H_)
767 #if defined(_I386_BUS_PIO_H_)
771 int _port_ = bsh + offset; \
772 __asm __volatile(" \n\
776 "=D" (_port_), "=S" (addr), "=c" (count) :
777 "0" (_port_), "1" (addr), "2" (count) :
783 #if 0 /* Cause a link error for bus_space_write_region_8 */
784 #define bus_space_write_region_8 \
785 !!! bus_space_write_region_8 unimplemented !!!
789 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
790 * by tag/handle/offset `count' times.
793 static __inline void bus_space_set_multi_1(bus_space_tag_t tag,
794 bus_space_handle_t bsh,
796 u_int8_t value, size_t count);
797 static __inline void bus_space_set_multi_2(bus_space_tag_t tag,
798 bus_space_handle_t bsh,
800 u_int16_t value, size_t count);
801 static __inline void bus_space_set_multi_4(bus_space_tag_t tag,
802 bus_space_handle_t bsh,
804 u_int32_t value, size_t count);
807 bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t bsh,
808 bus_size_t offset, u_int8_t value, size_t count)
810 bus_addr_t addr = bsh + offset;
812 #if defined(_I386_BUS_PIO_H_)
813 #if defined(_I386_BUS_MEMIO_H_)
814 if (tag == I386_BUS_SPACE_IO)
819 #if defined(_I386_BUS_MEMIO_H_)
820 #if defined(_I386_BUS_PIO_H_)
824 *(volatile u_int8_t *)(addr) = value;
829 bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t bsh,
830 bus_size_t offset, u_int16_t value, size_t count)
832 bus_addr_t addr = bsh + offset;
834 #if defined(_I386_BUS_PIO_H_)
835 #if defined(_I386_BUS_MEMIO_H_)
836 if (tag == I386_BUS_SPACE_IO)
841 #if defined(_I386_BUS_MEMIO_H_)
842 #if defined(_I386_BUS_PIO_H_)
846 *(volatile u_int16_t *)(addr) = value;
851 bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t bsh,
852 bus_size_t offset, u_int32_t value, size_t count)
854 bus_addr_t addr = bsh + offset;
856 #if defined(_I386_BUS_PIO_H_)
857 #if defined(_I386_BUS_MEMIO_H_)
858 if (tag == I386_BUS_SPACE_IO)
863 #if defined(_I386_BUS_MEMIO_H_)
864 #if defined(_I386_BUS_PIO_H_)
868 *(volatile u_int32_t *)(addr) = value;
872 #if 0 /* Cause a link error for bus_space_set_multi_8 */
873 #define bus_space_set_multi_8 !!! bus_space_set_multi_8 unimplemented !!!
877 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
878 * by tag/handle starting at `offset'.
881 static __inline void bus_space_set_region_1(bus_space_tag_t tag,
882 bus_space_handle_t bsh,
883 bus_size_t offset, u_int8_t value,
885 static __inline void bus_space_set_region_2(bus_space_tag_t tag,
886 bus_space_handle_t bsh,
887 bus_size_t offset, u_int16_t value,
889 static __inline void bus_space_set_region_4(bus_space_tag_t tag,
890 bus_space_handle_t bsh,
891 bus_size_t offset, u_int32_t value,
895 bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t bsh,
896 bus_size_t offset, u_int8_t value, size_t count)
898 bus_addr_t addr = bsh + offset;
900 #if defined(_I386_BUS_PIO_H_)
901 #if defined(_I386_BUS_MEMIO_H_)
902 if (tag == I386_BUS_SPACE_IO)
904 for (; count != 0; count--, addr++)
907 #if defined(_I386_BUS_MEMIO_H_)
908 #if defined(_I386_BUS_PIO_H_)
911 for (; count != 0; count--, addr++)
912 *(volatile u_int8_t *)(addr) = value;
917 bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t bsh,
918 bus_size_t offset, u_int16_t value, size_t count)
920 bus_addr_t addr = bsh + offset;
922 #if defined(_I386_BUS_PIO_H_)
923 #if defined(_I386_BUS_MEMIO_H_)
924 if (tag == I386_BUS_SPACE_IO)
926 for (; count != 0; count--, addr += 2)
929 #if defined(_I386_BUS_MEMIO_H_)
930 #if defined(_I386_BUS_PIO_H_)
933 for (; count != 0; count--, addr += 2)
934 *(volatile u_int16_t *)(addr) = value;
939 bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t bsh,
940 bus_size_t offset, u_int32_t value, size_t count)
942 bus_addr_t addr = bsh + offset;
944 #if defined(_I386_BUS_PIO_H_)
945 #if defined(_I386_BUS_MEMIO_H_)
946 if (tag == I386_BUS_SPACE_IO)
948 for (; count != 0; count--, addr += 4)
951 #if defined(_I386_BUS_MEMIO_H_)
952 #if defined(_I386_BUS_PIO_H_)
955 for (; count != 0; count--, addr += 4)
956 *(volatile u_int32_t *)(addr) = value;
960 #if 0 /* Cause a link error for bus_space_set_region_8 */
961 #define bus_space_set_region_8 !!! bus_space_set_region_8 unimplemented !!!
965 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
966 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
969 static __inline void bus_space_copy_region_1(bus_space_tag_t tag,
970 bus_space_handle_t bsh1,
972 bus_space_handle_t bsh2,
973 bus_size_t off2, size_t count);
975 static __inline void bus_space_copy_region_2(bus_space_tag_t tag,
976 bus_space_handle_t bsh1,
978 bus_space_handle_t bsh2,
979 bus_size_t off2, size_t count);
981 static __inline void bus_space_copy_region_4(bus_space_tag_t tag,
982 bus_space_handle_t bsh1,
984 bus_space_handle_t bsh2,
985 bus_size_t off2, size_t count);
988 bus_space_copy_region_1(bus_space_tag_t tag, bus_space_handle_t bsh1,
989 bus_size_t off1, bus_space_handle_t bsh2,
990 bus_size_t off2, size_t count)
992 bus_addr_t addr1 = bsh1 + off1;
993 bus_addr_t addr2 = bsh2 + off2;
995 #if defined(_I386_BUS_PIO_H_)
996 #if defined(_I386_BUS_MEMIO_H_)
997 if (tag == I386_BUS_SPACE_IO)
1000 if (addr1 >= addr2) {
1001 /* src after dest: copy forward */
1002 for (; count != 0; count--, addr1++, addr2++)
1003 outb(addr2, inb(addr1));
1005 /* dest after src: copy backwards */
1006 for (addr1 += (count - 1), addr2 += (count - 1);
1007 count != 0; count--, addr1--, addr2--)
1008 outb(addr2, inb(addr1));
1012 #if defined(_I386_BUS_MEMIO_H_)
1013 #if defined(_I386_BUS_PIO_H_)
1017 if (addr1 >= addr2) {
1018 /* src after dest: copy forward */
1019 for (; count != 0; count--, addr1++, addr2++)
1020 *(volatile u_int8_t *)(addr2) =
1021 *(volatile u_int8_t *)(addr1);
1023 /* dest after src: copy backwards */
1024 for (addr1 += (count - 1), addr2 += (count - 1);
1025 count != 0; count--, addr1--, addr2--)
1026 *(volatile u_int8_t *)(addr2) =
1027 *(volatile u_int8_t *)(addr1);
1033 static __inline void
1034 bus_space_copy_region_2(bus_space_tag_t tag, bus_space_handle_t bsh1,
1035 bus_size_t off1, bus_space_handle_t bsh2,
1036 bus_size_t off2, size_t count)
1038 bus_addr_t addr1 = bsh1 + off1;
1039 bus_addr_t addr2 = bsh2 + off2;
1041 #if defined(_I386_BUS_PIO_H_)
1042 #if defined(_I386_BUS_MEMIO_H_)
1043 if (tag == I386_BUS_SPACE_IO)
1046 if (addr1 >= addr2) {
1047 /* src after dest: copy forward */
1048 for (; count != 0; count--, addr1 += 2, addr2 += 2)
1049 outw(addr2, inw(addr1));
1051 /* dest after src: copy backwards */
1052 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1053 count != 0; count--, addr1 -= 2, addr2 -= 2)
1054 outw(addr2, inw(addr1));
1058 #if defined(_I386_BUS_MEMIO_H_)
1059 #if defined(_I386_BUS_PIO_H_)
1063 if (addr1 >= addr2) {
1064 /* src after dest: copy forward */
1065 for (; count != 0; count--, addr1 += 2, addr2 += 2)
1066 *(volatile u_int16_t *)(addr2) =
1067 *(volatile u_int16_t *)(addr1);
1069 /* dest after src: copy backwards */
1070 for (addr1 += 2 * (count - 1), addr2 += 2 * (count - 1);
1071 count != 0; count--, addr1 -= 2, addr2 -= 2)
1072 *(volatile u_int16_t *)(addr2) =
1073 *(volatile u_int16_t *)(addr1);
1079 static __inline void
1080 bus_space_copy_region_4(bus_space_tag_t tag, bus_space_handle_t bsh1,
1081 bus_size_t off1, bus_space_handle_t bsh2,
1082 bus_size_t off2, size_t count)
1084 bus_addr_t addr1 = bsh1 + off1;
1085 bus_addr_t addr2 = bsh2 + off2;
1087 #if defined(_I386_BUS_PIO_H_)
1088 #if defined(_I386_BUS_MEMIO_H_)
1089 if (tag == I386_BUS_SPACE_IO)
1092 if (addr1 >= addr2) {
1093 /* src after dest: copy forward */
1094 for (; count != 0; count--, addr1 += 4, addr2 += 4)
1095 outl(addr2, inl(addr1));
1097 /* dest after src: copy backwards */
1098 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1099 count != 0; count--, addr1 -= 4, addr2 -= 4)
1100 outl(addr2, inl(addr1));
1104 #if defined(_I386_BUS_MEMIO_H_)
1105 #if defined(_I386_BUS_PIO_H_)
1109 if (addr1 >= addr2) {
1110 /* src after dest: copy forward */
1111 for (; count != 0; count--, addr1 += 4, addr2 += 4)
1112 *(volatile u_int32_t *)(addr2) =
1113 *(volatile u_int32_t *)(addr1);
1115 /* dest after src: copy backwards */
1116 for (addr1 += 4 * (count - 1), addr2 += 4 * (count - 1);
1117 count != 0; count--, addr1 -= 4, addr2 -= 4)
1118 *(volatile u_int32_t *)(addr2) =
1119 *(volatile u_int32_t *)(addr1);
1125 #endif /* defined(_I386_BUS_PIO_H_) || defined(_I386_MEM_IO_H_) */
1127 #if 0 /* Cause a link error for bus_space_copy_8 */
1128 #define bus_space_copy_region_8 !!! bus_space_copy_region_8 unimplemented !!!
1132 * Bus read/write barrier methods.
1134 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
1135 * bus_size_t offset, bus_size_t len, int flags);
1138 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
1139 * prevent reordering by the compiler; all Intel x86 processors currently
1140 * retire operations outside the CPU in program order.
1142 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
1143 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
1145 static __inline void
1146 bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
1147 bus_size_t offset, bus_size_t len, int flags)
1149 if (flags & BUS_SPACE_BARRIER_READ)
1150 __asm __volatile("lock; addl $0,0(%%esp)" : : : "memory");
1152 __asm __volatile("" : : : "memory");
1156 * Flags used in various bus DMA methods.
1158 #define BUS_DMA_WAITOK 0x00 /* safe to sleep (pseudo-flag) */
1159 #define BUS_DMA_NOWAIT 0x01 /* not safe to sleep */
1160 #define BUS_DMA_ALLOCNOW 0x02 /* perform resource allocation now */
1161 #define BUS_DMAMEM_NOSYNC 0x04 /* map memory to not require sync */
1162 #define BUS_DMA_BUS1 0x10 /* placeholders for bus functions... */
1163 #define BUS_DMA_BUS2 0x20
1164 #define BUS_DMA_BUS3 0x40
1165 #define BUS_DMA_BUS4 0x80
1167 /* Forwards needed by prototypes below. */
1174 * Operations performed by bus_dmamap_sync().
1177 BUS_DMASYNC_PREREAD,
1178 BUS_DMASYNC_POSTREAD,
1179 BUS_DMASYNC_PREWRITE,
1180 BUS_DMASYNC_POSTWRITE
1186 * A machine-dependent opaque type describing the characteristics
1187 * of how to perform DMA mappings. This structure encapsultes
1188 * information concerning address and alignment restrictions, number
1189 * of S/G segments, amount of data per S/G segment, etc.
1191 typedef struct bus_dma_tag *bus_dma_tag_t;
1196 * DMA mapping instance information.
1198 typedef struct bus_dmamap *bus_dmamap_t;
1203 * Describes a single contiguous DMA transaction. Values
1204 * are suitable for programming into DMA registers.
1206 typedef struct bus_dma_segment {
1207 bus_addr_t ds_addr; /* DMA address */
1208 bus_size_t ds_len; /* length of transfer */
1209 } bus_dma_segment_t;
1212 * A function that returns 1 if the address cannot be accessed by
1213 * a device and 0 if it can be.
1215 typedef int bus_dma_filter_t(void *, bus_addr_t);
1218 * Allocate a device specific dma_tag encapsulating the constraints of
1219 * the parent tag in addition to other restrictions specified:
1221 * alignment: alignment for segments.
1222 * boundary: Boundary that segments cannot cross.
1223 * lowaddr: Low restricted address that cannot appear in a mapping.
1224 * highaddr: High restricted address that cannot appear in a mapping.
1225 * filtfunc: An optional function to further test if an address
1226 * within the range of lowaddr and highaddr cannot appear
1228 * filtfuncarg: An argument that will be passed to filtfunc in addition
1229 * to the address to test.
1230 * maxsize: Maximum mapping size supported by this tag.
1231 * nsegments: Number of discontinuities allowed in maps.
1232 * maxsegsz: Maximum size of a segment in the map.
1233 * flags: Bus DMA flags.
1234 * dmat: A pointer to set to a valid dma tag should the return
1235 * value of this function indicate success.
1237 /* XXX Should probably allow specification of alignment */
1238 int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignemnt,
1239 bus_size_t boundary, bus_addr_t lowaddr,
1240 bus_addr_t highaddr, bus_dma_filter_t *filtfunc,
1241 void *filtfuncarg, bus_size_t maxsize, int nsegments,
1242 bus_size_t maxsegsz, int flags, bus_dma_tag_t *dmat);
1244 int bus_dma_tag_destroy(bus_dma_tag_t dmat);
1247 * Allocate a handle for mapping from kva/uva/physical
1248 * address space into bus device space.
1250 int bus_dmamap_create(bus_dma_tag_t dmat, int flags, bus_dmamap_t *mapp);
1253 * Destroy a handle for mapping from kva/uva/physical
1254 * address space into bus device space.
1256 int bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map);
1259 * Allocate a piece of memory that can be efficiently mapped into
1260 * bus device space based on the constraints lited in the dma tag.
1261 * A dmamap to for use with dmamap_load is also allocated.
1263 int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags,
1264 bus_dmamap_t *mapp);
1267 * Free a piece of memory and it's allociated dmamap, that was allocated
1268 * via bus_dmamem_alloc.
1270 void bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map);
1273 * A function that processes a successfully loaded dma map or an error
1274 * from a delayed load map.
1276 typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int);
1279 * Map the buffer buf into bus space using the dmamap map.
1281 int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf,
1282 bus_size_t buflen, bus_dmamap_callback_t *callback,
1283 void *callback_arg, int flags);
1286 * Perform a syncronization operation on the given map.
1288 void _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_dmasync_op_t);
1289 #define bus_dmamap_sync(dmat, dmamap, op) \
1290 if ((dmamap) != NULL) \
1291 _bus_dmamap_sync(dmat, dmamap, op)
1294 * Release the mapping held by map.
1296 void _bus_dmamap_unload(bus_dma_tag_t dmat, bus_dmamap_t map);
1297 #define bus_dmamap_unload(dmat, dmamap) \
1298 if ((dmamap) != NULL) \
1299 _bus_dmamap_unload(dmat, dmamap)
1301 #endif /* _I386_BUS_AT386_H_ */