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.
70 * $FreeBSD: src/sys/i386/include/bus_at386.h,v 1.8.2.3 2002/03/03 05:42:50 nyan Exp $
71 * $DragonFly: src/sys/cpu/i386/include/bus_at386.h,v 1.10 2006/11/07 06:43:22 dillon Exp $
74 #ifndef _CPU_BUS_AT386_H_
75 #define _CPU_BUS_AT386_H_
77 #include <machine/cpufunc.h>
80 * Values for the i386 bus space tag, not to be used directly by MI code.
82 #define I386_BUS_SPACE_IO 0 /* space is i/o space */
83 #define I386_BUS_SPACE_MEM 1 /* space is mem space */
86 * Bus address and size types
88 typedef u_int32_t bus_addr_t
;
89 typedef u_int32_t bus_size_t
;
91 #define BUS_SPACE_MAXSIZE_24BIT 0xFFFFFF
92 #define BUS_SPACE_MAXSIZE_32BIT 0xFFFFFFFF
93 #define BUS_SPACE_MAXSIZE (64 * 1024) /* Maximum supported size */
94 #define BUS_SPACE_MAXADDR_24BIT 0xFFFFFF
95 #define BUS_SPACE_MAXADDR_32BIT 0xFFFFFFFF
96 #define BUS_SPACE_MAXADDR BUS_SPACE_MAXADDR_32BIT
98 #define BUS_SPACE_UNRESTRICTED (~0)
101 * Access methods for bus resources and address space.
103 typedef int bus_space_tag_t
;
104 typedef u_int bus_space_handle_t
;
107 * Map a region of device bus space into CPU virtual address space.
110 #define BUS_SPACE_MAP_CACHEABLE 0x01
111 #define BUS_SPACE_MAP_LINEAR 0x02
113 int bus_space_map(bus_space_tag_t t
, bus_addr_t addr
, bus_size_t size
,
114 int flags
, bus_space_handle_t
*bshp
);
117 * Unmap a region of device bus space.
120 static __inline
void bus_space_unmap(bus_space_tag_t t
, bus_space_handle_t bsh
,
124 bus_space_unmap(bus_space_tag_t t __unused
, bus_space_handle_t bsh __unused
, bus_size_t size __unused
)
129 * Get a new handle for a subregion of an already-mapped area of bus space.
132 static __inline
int bus_space_subregion(bus_space_tag_t t
,
133 bus_space_handle_t bsh
,
134 bus_size_t offset
, bus_size_t size
,
135 bus_space_handle_t
*nbshp
);
138 bus_space_subregion(bus_space_tag_t t __unused
, bus_space_handle_t bsh
,
139 bus_size_t offset
, bus_size_t size __unused
,
140 bus_space_handle_t
*nbshp
)
143 *nbshp
= bsh
+ offset
;
147 static __inline
void *
148 bus_space_kva(bus_space_tag_t tag
, bus_space_handle_t handle
, bus_size_t offset
)
150 if (tag
== I386_BUS_SPACE_IO
)
152 return ((void *)(handle
+ offset
));
156 * Allocate a region of memory that is accessible to devices in bus space.
159 int bus_space_alloc(bus_space_tag_t t
, bus_addr_t rstart
,
160 bus_addr_t rend
, bus_size_t size
, bus_size_t align
,
161 bus_size_t boundary
, int flags
, bus_addr_t
*addrp
,
162 bus_space_handle_t
*bshp
);
165 * Free a region of bus space accessible memory.
168 static __inline
void bus_space_free(bus_space_tag_t t
, bus_space_handle_t bsh
,
172 bus_space_free(bus_space_tag_t t __unused
, bus_space_handle_t bsh __unused
, bus_size_t size __unused
)
177 * Read a 1, 2, 4, or 8 byte quantity from bus space
178 * described by tag/handle/offset.
180 static __inline u_int8_t
bus_space_read_1(bus_space_tag_t tag
,
181 bus_space_handle_t handle
,
184 static __inline u_int16_t
bus_space_read_2(bus_space_tag_t tag
,
185 bus_space_handle_t handle
,
188 static __inline u_int32_t
bus_space_read_4(bus_space_tag_t tag
,
189 bus_space_handle_t handle
,
192 static __inline u_int8_t
193 bus_space_read_1(bus_space_tag_t tag
, bus_space_handle_t handle
,
196 if (tag
== I386_BUS_SPACE_IO
)
197 return (inb(handle
+ offset
));
198 return (*(volatile u_int8_t
*)(handle
+ offset
));
201 static __inline u_int16_t
202 bus_space_read_2(bus_space_tag_t tag
, bus_space_handle_t handle
,
205 if (tag
== I386_BUS_SPACE_IO
)
206 return (inw(handle
+ offset
));
207 return (*(volatile u_int16_t
*)(handle
+ offset
));
210 static __inline u_int32_t
211 bus_space_read_4(bus_space_tag_t tag
, bus_space_handle_t handle
,
214 if (tag
== I386_BUS_SPACE_IO
)
215 return (inl(handle
+ offset
));
216 return (*(volatile u_int32_t
*)(handle
+ offset
));
220 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
221 * described by tag/handle/offset and copy into buffer provided.
223 static __inline
void bus_space_read_multi_1(bus_space_tag_t tag
,
224 bus_space_handle_t bsh
,
225 bus_size_t offset
, u_int8_t
*addr
,
228 static __inline
void bus_space_read_multi_2(bus_space_tag_t tag
,
229 bus_space_handle_t bsh
,
230 bus_size_t offset
, u_int16_t
*addr
,
233 static __inline
void bus_space_read_multi_4(bus_space_tag_t tag
,
234 bus_space_handle_t bsh
,
235 bus_size_t offset
, u_int32_t
*addr
,
239 bus_space_read_multi_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
240 bus_size_t offset
, u_int8_t
*addr
, size_t count
)
242 if (tag
== I386_BUS_SPACE_IO
) {
243 insb(bsh
+ offset
, addr
, count
);
245 __asm
__volatile(" \n\
247 1: movb (%2),%%al \n\
250 "=D" (addr
), "=c" (count
) :
251 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
257 bus_space_read_multi_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
258 bus_size_t offset
, u_int16_t
*addr
, size_t count
)
260 if (tag
== I386_BUS_SPACE_IO
) {
261 insw(bsh
+ offset
, addr
, count
);
263 __asm
__volatile(" \n\
265 1: movw (%2),%%ax \n\
268 "=D" (addr
), "=c" (count
) :
269 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
275 bus_space_read_multi_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
276 bus_size_t offset
, u_int32_t
*addr
, size_t count
)
278 if (tag
== I386_BUS_SPACE_IO
) {
279 insl(bsh
+ offset
, addr
, count
);
281 __asm
__volatile(" \n\
283 1: movl (%2),%%eax \n\
286 "=D" (addr
), "=c" (count
) :
287 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
293 * Read `count' 1, 2, 4, or 8 byte quantities from bus space
294 * described by tag/handle and starting at `offset' and copy into
297 static __inline
void bus_space_read_region_1(bus_space_tag_t tag
,
298 bus_space_handle_t bsh
,
299 bus_size_t offset
, u_int8_t
*addr
,
302 static __inline
void bus_space_read_region_2(bus_space_tag_t tag
,
303 bus_space_handle_t bsh
,
304 bus_size_t offset
, u_int16_t
*addr
,
307 static __inline
void bus_space_read_region_4(bus_space_tag_t tag
,
308 bus_space_handle_t bsh
,
309 bus_size_t offset
, u_int32_t
*addr
,
314 bus_space_read_region_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
315 bus_size_t offset
, u_int8_t
*addr
, size_t count
)
317 if (tag
== I386_BUS_SPACE_IO
) {
318 int _port_
= bsh
+ offset
; \
319 __asm
__volatile(" \n\
325 "=D" (addr
), "=c" (count
), "=d" (_port_
) :
326 "0" (addr
), "1" (count
), "2" (_port_
) :
327 "%eax", "memory", "cc");
329 int _port_
= bsh
+ offset
; \
330 __asm
__volatile(" \n\
334 "=D" (addr
), "=c" (count
), "=S" (_port_
) :
335 "0" (addr
), "1" (count
), "2" (_port_
) :
341 bus_space_read_region_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
342 bus_size_t offset
, u_int16_t
*addr
, size_t count
)
344 if (tag
== I386_BUS_SPACE_IO
) {
345 int _port_
= bsh
+ offset
; \
346 __asm
__volatile(" \n\
352 "=D" (addr
), "=c" (count
), "=d" (_port_
) :
353 "0" (addr
), "1" (count
), "2" (_port_
) :
354 "%eax", "memory", "cc");
356 int _port_
= bsh
+ offset
; \
357 __asm
__volatile(" \n\
361 "=D" (addr
), "=c" (count
), "=S" (_port_
) :
362 "0" (addr
), "1" (count
), "2" (_port_
) :
368 bus_space_read_region_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
369 bus_size_t offset
, u_int32_t
*addr
, size_t count
)
371 if (tag
== I386_BUS_SPACE_IO
) {
372 int _port_
= bsh
+ offset
; \
373 __asm
__volatile(" \n\
379 "=D" (addr
), "=c" (count
), "=d" (_port_
) :
380 "0" (addr
), "1" (count
), "2" (_port_
) :
381 "%eax", "memory", "cc");
383 int _port_
= bsh
+ offset
; \
384 __asm
__volatile(" \n\
388 "=D" (addr
), "=c" (count
), "=S" (_port_
) :
389 "0" (addr
), "1" (count
), "2" (_port_
) :
395 * Write the 1, 2, 4, or 8 byte value `value' to bus space
396 * described by tag/handle/offset.
399 static __inline
void bus_space_write_1(bus_space_tag_t tag
,
400 bus_space_handle_t bsh
,
401 bus_size_t offset
, u_int8_t value
);
403 static __inline
void bus_space_write_2(bus_space_tag_t tag
,
404 bus_space_handle_t bsh
,
405 bus_size_t offset
, u_int16_t value
);
407 static __inline
void bus_space_write_4(bus_space_tag_t tag
,
408 bus_space_handle_t bsh
,
409 bus_size_t offset
, u_int32_t value
);
412 bus_space_write_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
413 bus_size_t offset
, u_int8_t value
)
415 if (tag
== I386_BUS_SPACE_IO
)
416 outb(bsh
+ offset
, value
);
418 *(volatile u_int8_t
*)(bsh
+ offset
) = value
;
422 bus_space_write_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
423 bus_size_t offset
, u_int16_t value
)
425 if (tag
== I386_BUS_SPACE_IO
)
426 outw(bsh
+ offset
, value
);
428 *(volatile u_int16_t
*)(bsh
+ offset
) = value
;
432 bus_space_write_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
433 bus_size_t offset
, u_int32_t value
)
435 if (tag
== I386_BUS_SPACE_IO
)
436 outl(bsh
+ offset
, value
);
438 *(volatile u_int32_t
*)(bsh
+ offset
) = value
;
442 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
443 * provided to bus space described by tag/handle/offset.
446 static __inline
void bus_space_write_multi_1(bus_space_tag_t tag
,
447 bus_space_handle_t bsh
,
449 const u_int8_t
*addr
,
451 static __inline
void bus_space_write_multi_2(bus_space_tag_t tag
,
452 bus_space_handle_t bsh
,
454 const u_int16_t
*addr
,
457 static __inline
void bus_space_write_multi_4(bus_space_tag_t tag
,
458 bus_space_handle_t bsh
,
460 const u_int32_t
*addr
,
464 bus_space_write_multi_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
465 bus_size_t offset
, const u_int8_t
*addr
, size_t count
)
467 if (tag
== I386_BUS_SPACE_IO
) {
468 outsb(bsh
+ offset
, addr
, count
);
470 __asm
__volatile(" \n\
475 "=S" (addr
), "=c" (count
) :
476 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
477 "%eax", "memory", "cc");
482 bus_space_write_multi_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
483 bus_size_t offset
, const u_int16_t
*addr
, size_t count
)
485 if (tag
== I386_BUS_SPACE_IO
) {
486 outsw(bsh
+ offset
, addr
, count
);
488 __asm
__volatile(" \n\
493 "=S" (addr
), "=c" (count
) :
494 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
495 "%eax", "memory", "cc");
500 bus_space_write_multi_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
501 bus_size_t offset
, const u_int32_t
*addr
, size_t count
)
503 if (tag
== I386_BUS_SPACE_IO
) {
504 outsl(bsh
+ offset
, addr
, count
);
506 __asm
__volatile(" \n\
511 "=S" (addr
), "=c" (count
) :
512 "r" (bsh
+ offset
), "0" (addr
), "1" (count
) :
513 "%eax", "memory", "cc");
518 * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
519 * to bus space described by tag/handle starting at `offset'.
522 static __inline
void bus_space_write_region_1(bus_space_tag_t tag
,
523 bus_space_handle_t bsh
,
525 const u_int8_t
*addr
,
527 static __inline
void bus_space_write_region_2(bus_space_tag_t tag
,
528 bus_space_handle_t bsh
,
530 const u_int16_t
*addr
,
532 static __inline
void bus_space_write_region_4(bus_space_tag_t tag
,
533 bus_space_handle_t bsh
,
535 const u_int32_t
*addr
,
539 bus_space_write_region_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
540 bus_size_t offset
, const u_int8_t
*addr
, size_t count
)
542 if (tag
== I386_BUS_SPACE_IO
) {
543 int _port_
= bsh
+ offset
; \
544 __asm
__volatile(" \n\
550 "=d" (_port_
), "=S" (addr
), "=c" (count
) :
551 "0" (_port_
), "1" (addr
), "2" (count
) :
552 "%eax", "memory", "cc");
554 int _port_
= bsh
+ offset
; \
555 __asm
__volatile(" \n\
559 "=D" (_port_
), "=S" (addr
), "=c" (count
) :
560 "0" (_port_
), "1" (addr
), "2" (count
) :
566 bus_space_write_region_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
567 bus_size_t offset
, const u_int16_t
*addr
, size_t count
)
569 if (tag
== I386_BUS_SPACE_IO
) {
570 int _port_
= bsh
+ offset
; \
571 __asm
__volatile(" \n\
577 "=d" (_port_
), "=S" (addr
), "=c" (count
) :
578 "0" (_port_
), "1" (addr
), "2" (count
) :
579 "%eax", "memory", "cc");
581 int _port_
= bsh
+ offset
; \
582 __asm
__volatile(" \n\
586 "=D" (_port_
), "=S" (addr
), "=c" (count
) :
587 "0" (_port_
), "1" (addr
), "2" (count
) :
593 bus_space_write_region_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
594 bus_size_t offset
, const u_int32_t
*addr
, size_t count
)
596 if (tag
== I386_BUS_SPACE_IO
) {
597 int _port_
= bsh
+ offset
; \
598 __asm
__volatile(" \n\
604 "=d" (_port_
), "=S" (addr
), "=c" (count
) :
605 "0" (_port_
), "1" (addr
), "2" (count
) :
606 "%eax", "memory", "cc");
608 int _port_
= bsh
+ offset
; \
609 __asm
__volatile(" \n\
613 "=D" (_port_
), "=S" (addr
), "=c" (count
) :
614 "0" (_port_
), "1" (addr
), "2" (count
) :
620 * Write the 1, 2, 4, or 8 byte value `val' to bus space described
621 * by tag/handle/offset `count' times.
624 static __inline
void bus_space_set_multi_1(bus_space_tag_t tag
,
625 bus_space_handle_t bsh
,
627 u_int8_t value
, size_t count
);
628 static __inline
void bus_space_set_multi_2(bus_space_tag_t tag
,
629 bus_space_handle_t bsh
,
631 u_int16_t value
, size_t count
);
632 static __inline
void bus_space_set_multi_4(bus_space_tag_t tag
,
633 bus_space_handle_t bsh
,
635 u_int32_t value
, size_t count
);
638 bus_space_set_multi_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
639 bus_size_t offset
, u_int8_t value
, size_t count
)
641 bus_space_handle_t addr
= bsh
+ offset
;
643 if (tag
== I386_BUS_SPACE_IO
) {
648 *(volatile u_int8_t
*)(addr
) = value
;
653 bus_space_set_multi_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
654 bus_size_t offset
, u_int16_t value
, size_t count
)
656 bus_space_handle_t addr
= bsh
+ offset
;
658 if (tag
== I386_BUS_SPACE_IO
) {
663 *(volatile u_int16_t
*)(addr
) = value
;
668 bus_space_set_multi_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
669 bus_size_t offset
, u_int32_t value
, size_t count
)
671 bus_space_handle_t addr
= bsh
+ offset
;
673 if (tag
== I386_BUS_SPACE_IO
) {
678 *(volatile u_int32_t
*)(addr
) = value
;
683 * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
684 * by tag/handle starting at `offset'.
687 static __inline
void bus_space_set_region_1(bus_space_tag_t tag
,
688 bus_space_handle_t bsh
,
689 bus_size_t offset
, u_int8_t value
,
691 static __inline
void bus_space_set_region_2(bus_space_tag_t tag
,
692 bus_space_handle_t bsh
,
693 bus_size_t offset
, u_int16_t value
,
695 static __inline
void bus_space_set_region_4(bus_space_tag_t tag
,
696 bus_space_handle_t bsh
,
697 bus_size_t offset
, u_int32_t value
,
701 bus_space_set_region_1(bus_space_tag_t tag
, bus_space_handle_t bsh
,
702 bus_size_t offset
, u_int8_t value
, size_t count
)
704 bus_space_handle_t addr
= bsh
+ offset
;
706 if (tag
== I386_BUS_SPACE_IO
) {
707 for (; count
!= 0; count
--, addr
++)
710 for (; count
!= 0; count
--, addr
++)
711 *(volatile u_int8_t
*)(addr
) = value
;
716 bus_space_set_region_2(bus_space_tag_t tag
, bus_space_handle_t bsh
,
717 bus_size_t offset
, u_int16_t value
, size_t count
)
719 bus_space_handle_t addr
= bsh
+ offset
;
721 if (tag
== I386_BUS_SPACE_IO
) {
722 for (; count
!= 0; count
--, addr
+= 2)
725 for (; count
!= 0; count
--, addr
+= 2)
726 *(volatile u_int16_t
*)(addr
) = value
;
731 bus_space_set_region_4(bus_space_tag_t tag
, bus_space_handle_t bsh
,
732 bus_size_t offset
, u_int32_t value
, size_t count
)
734 bus_space_handle_t addr
= bsh
+ offset
;
736 if (tag
== I386_BUS_SPACE_IO
) {
737 for (; count
!= 0; count
--, addr
+= 4)
740 for (; count
!= 0; count
--, addr
+= 4)
741 *(volatile u_int32_t
*)(addr
) = value
;
746 * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
747 * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
750 static __inline
void bus_space_copy_region_1(bus_space_tag_t tag
,
751 bus_space_handle_t bsh1
,
753 bus_space_handle_t bsh2
,
754 bus_size_t off2
, size_t count
);
756 static __inline
void bus_space_copy_region_2(bus_space_tag_t tag
,
757 bus_space_handle_t bsh1
,
759 bus_space_handle_t bsh2
,
760 bus_size_t off2
, size_t count
);
762 static __inline
void bus_space_copy_region_4(bus_space_tag_t tag
,
763 bus_space_handle_t bsh1
,
765 bus_space_handle_t bsh2
,
766 bus_size_t off2
, size_t count
);
769 bus_space_copy_region_1(bus_space_tag_t tag
, bus_space_handle_t bsh1
,
770 bus_size_t off1
, bus_space_handle_t bsh2
,
771 bus_size_t off2
, size_t count
)
773 bus_space_handle_t addr1
= bsh1
+ off1
;
774 bus_space_handle_t addr2
= bsh2
+ off2
;
776 if (tag
== I386_BUS_SPACE_IO
) {
777 if (addr1
>= addr2
) {
778 /* src after dest: copy forward */
779 for (; count
!= 0; count
--, addr1
++, addr2
++)
780 outb(addr2
, inb(addr1
));
782 /* dest after src: copy backwards */
783 for (addr1
+= (count
- 1), addr2
+= (count
- 1);
784 count
!= 0; count
--, addr1
--, addr2
--)
785 outb(addr2
, inb(addr1
));
788 if (addr1
>= addr2
) {
789 /* src after dest: copy forward */
790 for (; count
!= 0; count
--, addr1
++, addr2
++)
791 *(volatile u_int8_t
*)(addr2
) =
792 *(volatile u_int8_t
*)(addr1
);
794 /* dest after src: copy backwards */
795 for (addr1
+= (count
- 1), addr2
+= (count
- 1);
796 count
!= 0; count
--, addr1
--, addr2
--)
797 *(volatile u_int8_t
*)(addr2
) =
798 *(volatile u_int8_t
*)(addr1
);
804 bus_space_copy_region_2(bus_space_tag_t tag
, bus_space_handle_t bsh1
,
805 bus_size_t off1
, bus_space_handle_t bsh2
,
806 bus_size_t off2
, size_t count
)
808 bus_space_handle_t addr1
= bsh1
+ off1
;
809 bus_space_handle_t addr2
= bsh2
+ off2
;
811 if (tag
== I386_BUS_SPACE_IO
) {
812 if (addr1
>= addr2
) {
813 /* src after dest: copy forward */
814 for (; count
!= 0; count
--, addr1
+= 2, addr2
+= 2)
815 outw(addr2
, inw(addr1
));
817 /* dest after src: copy backwards */
818 for (addr1
+= 2 * (count
- 1), addr2
+= 2 * (count
- 1);
819 count
!= 0; count
--, addr1
-= 2, addr2
-= 2)
820 outw(addr2
, inw(addr1
));
823 if (addr1
>= addr2
) {
824 /* src after dest: copy forward */
825 for (; count
!= 0; count
--, addr1
+= 2, addr2
+= 2)
826 *(volatile u_int16_t
*)(addr2
) =
827 *(volatile u_int16_t
*)(addr1
);
829 /* dest after src: copy backwards */
830 for (addr1
+= 2 * (count
- 1), addr2
+= 2 * (count
- 1);
831 count
!= 0; count
--, addr1
-= 2, addr2
-= 2)
832 *(volatile u_int16_t
*)(addr2
) =
833 *(volatile u_int16_t
*)(addr1
);
839 bus_space_copy_region_4(bus_space_tag_t tag
, bus_space_handle_t bsh1
,
840 bus_size_t off1
, bus_space_handle_t bsh2
,
841 bus_size_t off2
, size_t count
)
843 bus_space_handle_t addr1
= bsh1
+ off1
;
844 bus_space_handle_t addr2
= bsh2
+ off2
;
846 if (tag
== I386_BUS_SPACE_IO
) {
847 if (addr1
>= addr2
) {
848 /* src after dest: copy forward */
849 for (; count
!= 0; count
--, addr1
+= 4, addr2
+= 4)
850 outl(addr2
, inl(addr1
));
852 /* dest after src: copy backwards */
853 for (addr1
+= 4 * (count
- 1), addr2
+= 4 * (count
- 1);
854 count
!= 0; count
--, addr1
-= 4, addr2
-= 4)
855 outl(addr2
, inl(addr1
));
858 if (addr1
>= addr2
) {
859 /* src after dest: copy forward */
860 for (; count
!= 0; count
--, addr1
+= 4, addr2
+= 4)
861 *(volatile u_int32_t
*)(addr2
) =
862 *(volatile u_int32_t
*)(addr1
);
864 /* dest after src: copy backwards */
865 for (addr1
+= 4 * (count
- 1), addr2
+= 4 * (count
- 1);
866 count
!= 0; count
--, addr1
-= 4, addr2
-= 4)
867 *(volatile u_int32_t
*)(addr2
) =
868 *(volatile u_int32_t
*)(addr1
);
874 * Bus read/write barrier methods.
876 * void bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
877 * bus_size_t offset, bus_size_t len, int flags);
879 * Note that BUS_SPACE_BARRIER_WRITE doesn't do anything other than
880 * prevent reordering by the compiler; all Intel x86 processors currently
881 * retire operations outside the CPU in program order.
883 #define BUS_SPACE_BARRIER_READ 0x01 /* force read barrier */
884 #define BUS_SPACE_BARRIER_WRITE 0x02 /* force write barrier */
887 bus_space_barrier(bus_space_tag_t tag __unused
, bus_space_handle_t bsh __unused
,
888 bus_size_t offset __unused
, bus_size_t len __unused
, int flags
)
890 if (flags
& BUS_SPACE_BARRIER_READ
)
891 __asm
__volatile("lock; addl $0,0(%%esp)" : : : "memory");
893 __asm
__volatile("" : : : "memory");
896 #endif /* _CPU_BUS_AT386_H_ */