fdisk - Use heads = 255 on file images
[dragonfly.git] / sys / cpu / i386 / include / bus_at386.h
bloba43c4ae6b56d7b0ed516a72a7f079747979739d2
1 /* $NetBSD: bus.h,v 1.12 1997/10/01 08:25:15 fvdl Exp $ */
3 /*-
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
5 * All rights reserved.
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
13 * are met:
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
46 * are met:
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,
121 bus_size_t size);
123 static __inline void
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);
137 static __inline int
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;
144 return (0);
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)
151 return ((void *)0);
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,
169 bus_size_t size);
171 static __inline void
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,
182 bus_size_t offset);
184 static __inline u_int16_t bus_space_read_2(bus_space_tag_t tag,
185 bus_space_handle_t handle,
186 bus_size_t offset);
188 static __inline u_int32_t bus_space_read_4(bus_space_tag_t tag,
189 bus_space_handle_t handle,
190 bus_size_t offset);
192 static __inline u_int8_t
193 bus_space_read_1(bus_space_tag_t tag, bus_space_handle_t handle,
194 bus_size_t offset)
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,
203 bus_size_t offset)
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,
212 bus_size_t offset)
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,
226 size_t count);
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,
231 size_t count);
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,
236 size_t count);
238 static __inline void
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);
244 } else {
245 __asm __volatile(" \n\
246 cld \n\
247 1: movb (%2),%%al \n\
248 stosb \n\
249 loop 1b" :
250 "=D" (addr), "=c" (count) :
251 "r" (bsh + offset), "0" (addr), "1" (count) :
252 "%eax", "memory");
256 static __inline void
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);
262 } else {
263 __asm __volatile(" \n\
264 cld \n\
265 1: movw (%2),%%ax \n\
266 stosw \n\
267 loop 1b" :
268 "=D" (addr), "=c" (count) :
269 "r" (bsh + offset), "0" (addr), "1" (count) :
270 "%eax", "memory");
274 static __inline void
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);
280 } else {
281 __asm __volatile(" \n\
282 cld \n\
283 1: movl (%2),%%eax \n\
284 stosl \n\
285 loop 1b" :
286 "=D" (addr), "=c" (count) :
287 "r" (bsh + offset), "0" (addr), "1" (count) :
288 "%eax", "memory");
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
295 * buffer provided.
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,
300 size_t count);
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,
305 size_t count);
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,
310 size_t count);
313 static __inline void
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\
320 cld \n\
321 1: inb %w2,%%al \n\
322 stosb \n\
323 incl %2 \n\
324 loop 1b" :
325 "=D" (addr), "=c" (count), "=d" (_port_) :
326 "0" (addr), "1" (count), "2" (_port_) :
327 "%eax", "memory", "cc");
328 } else {
329 int _port_ = bsh + offset; \
330 __asm __volatile(" \n\
331 cld \n\
332 repne \n\
333 movsb" :
334 "=D" (addr), "=c" (count), "=S" (_port_) :
335 "0" (addr), "1" (count), "2" (_port_) :
336 "memory", "cc");
340 static __inline void
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\
347 cld \n\
348 1: inw %w2,%%ax \n\
349 stosw \n\
350 addl $2,%2 \n\
351 loop 1b" :
352 "=D" (addr), "=c" (count), "=d" (_port_) :
353 "0" (addr), "1" (count), "2" (_port_) :
354 "%eax", "memory", "cc");
355 } else {
356 int _port_ = bsh + offset; \
357 __asm __volatile(" \n\
358 cld \n\
359 repne \n\
360 movsw" :
361 "=D" (addr), "=c" (count), "=S" (_port_) :
362 "0" (addr), "1" (count), "2" (_port_) :
363 "memory", "cc");
367 static __inline void
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\
374 cld \n\
375 1: inl %w2,%%eax \n\
376 stosl \n\
377 addl $4,%2 \n\
378 loop 1b" :
379 "=D" (addr), "=c" (count), "=d" (_port_) :
380 "0" (addr), "1" (count), "2" (_port_) :
381 "%eax", "memory", "cc");
382 } else {
383 int _port_ = bsh + offset; \
384 __asm __volatile(" \n\
385 cld \n\
386 repne \n\
387 movsl" :
388 "=D" (addr), "=c" (count), "=S" (_port_) :
389 "0" (addr), "1" (count), "2" (_port_) :
390 "memory", "cc");
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);
411 static __inline void
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);
417 else
418 *(volatile u_int8_t *)(bsh + offset) = value;
421 static __inline void
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);
427 else
428 *(volatile u_int16_t *)(bsh + offset) = value;
431 static __inline void
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);
437 else
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,
448 bus_size_t offset,
449 const u_int8_t *addr,
450 size_t count);
451 static __inline void bus_space_write_multi_2(bus_space_tag_t tag,
452 bus_space_handle_t bsh,
453 bus_size_t offset,
454 const u_int16_t *addr,
455 size_t count);
457 static __inline void bus_space_write_multi_4(bus_space_tag_t tag,
458 bus_space_handle_t bsh,
459 bus_size_t offset,
460 const u_int32_t *addr,
461 size_t count);
463 static __inline void
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);
469 } else {
470 __asm __volatile(" \n\
471 cld \n\
472 1: lodsb \n\
473 movb %%al,(%2) \n\
474 loop 1b" :
475 "=S" (addr), "=c" (count) :
476 "r" (bsh + offset), "0" (addr), "1" (count) :
477 "%eax", "memory", "cc");
481 static __inline void
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);
487 } else {
488 __asm __volatile(" \n\
489 cld \n\
490 1: lodsw \n\
491 movw %%ax,(%2) \n\
492 loop 1b" :
493 "=S" (addr), "=c" (count) :
494 "r" (bsh + offset), "0" (addr), "1" (count) :
495 "%eax", "memory", "cc");
499 static __inline void
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);
505 } else {
506 __asm __volatile(" \n\
507 cld \n\
508 1: lodsl \n\
509 movl %%eax,(%2) \n\
510 loop 1b" :
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,
524 bus_size_t offset,
525 const u_int8_t *addr,
526 size_t count);
527 static __inline void bus_space_write_region_2(bus_space_tag_t tag,
528 bus_space_handle_t bsh,
529 bus_size_t offset,
530 const u_int16_t *addr,
531 size_t count);
532 static __inline void bus_space_write_region_4(bus_space_tag_t tag,
533 bus_space_handle_t bsh,
534 bus_size_t offset,
535 const u_int32_t *addr,
536 size_t count);
538 static __inline void
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\
545 cld \n\
546 1: lodsb \n\
547 outb %%al,%w0 \n\
548 incl %0 \n\
549 loop 1b" :
550 "=d" (_port_), "=S" (addr), "=c" (count) :
551 "0" (_port_), "1" (addr), "2" (count) :
552 "%eax", "memory", "cc");
553 } else {
554 int _port_ = bsh + offset; \
555 __asm __volatile(" \n\
556 cld \n\
557 repne \n\
558 movsb" :
559 "=D" (_port_), "=S" (addr), "=c" (count) :
560 "0" (_port_), "1" (addr), "2" (count) :
561 "memory", "cc");
565 static __inline void
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\
572 cld \n\
573 1: lodsw \n\
574 outw %%ax,%w0 \n\
575 addl $2,%0 \n\
576 loop 1b" :
577 "=d" (_port_), "=S" (addr), "=c" (count) :
578 "0" (_port_), "1" (addr), "2" (count) :
579 "%eax", "memory", "cc");
580 } else {
581 int _port_ = bsh + offset; \
582 __asm __volatile(" \n\
583 cld \n\
584 repne \n\
585 movsw" :
586 "=D" (_port_), "=S" (addr), "=c" (count) :
587 "0" (_port_), "1" (addr), "2" (count) :
588 "memory", "cc");
592 static __inline void
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\
599 cld \n\
600 1: lodsl \n\
601 outl %%eax,%w0 \n\
602 addl $4,%0 \n\
603 loop 1b" :
604 "=d" (_port_), "=S" (addr), "=c" (count) :
605 "0" (_port_), "1" (addr), "2" (count) :
606 "%eax", "memory", "cc");
607 } else {
608 int _port_ = bsh + offset; \
609 __asm __volatile(" \n\
610 cld \n\
611 repne \n\
612 movsl" :
613 "=D" (_port_), "=S" (addr), "=c" (count) :
614 "0" (_port_), "1" (addr), "2" (count) :
615 "memory", "cc");
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,
626 bus_size_t offset,
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,
630 bus_size_t offset,
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,
634 bus_size_t offset,
635 u_int32_t value, size_t count);
637 static __inline void
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) {
644 while (count--)
645 outb(addr, value);
646 } else {
647 while (count--)
648 *(volatile u_int8_t *)(addr) = value;
652 static __inline void
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) {
659 while (count--)
660 outw(addr, value);
661 } else {
662 while (count--)
663 *(volatile u_int16_t *)(addr) = value;
667 static __inline void
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) {
674 while (count--)
675 outl(addr, value);
676 } else {
677 while (count--)
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,
690 size_t count);
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,
694 size_t count);
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,
698 size_t count);
700 static __inline void
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++)
708 outb(addr, value);
709 } else {
710 for (; count != 0; count--, addr++)
711 *(volatile u_int8_t *)(addr) = value;
715 static __inline void
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)
723 outw(addr, value);
724 } else {
725 for (; count != 0; count--, addr += 2)
726 *(volatile u_int16_t *)(addr) = value;
730 static __inline void
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)
738 outl(addr, value);
739 } else {
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,
752 bus_size_t off1,
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,
758 bus_size_t off1,
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,
764 bus_size_t off1,
765 bus_space_handle_t bsh2,
766 bus_size_t off2, size_t count);
768 static __inline void
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));
781 } else {
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));
787 } else {
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);
793 } else {
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);
803 static __inline void
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));
816 } else {
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));
822 } else {
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);
828 } else {
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);
838 static __inline void
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));
851 } else {
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));
857 } else {
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);
863 } else {
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 */
886 static __inline void
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");
892 else
893 __asm __volatile("" : : : "memory");
896 #endif /* _CPU_BUS_AT386_H_ */