[BACK]Return to bus.h CVS log [TXT][DIR] Up to [local] / sys / arch / amd64 / include

Annotation of sys/arch/amd64/include/bus.h, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: bus.h,v 1.5 2006/04/27 15:17:12 mickey Exp $  */
                      2: /*     $NetBSD: bus.h,v 1.6 1996/11/10 03:19:25 thorpej Exp $  */
                      3:
                      4: /*-
                      5:  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                     10:  * NASA Ames Research Center.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *     This product includes software developed by the NetBSD
                     23:  *     Foundation, Inc. and its contributors.
                     24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     25:  *    contributors may be used to endorse or promote products derived
                     26:  *    from this software without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     38:  * POSSIBILITY OF SUCH DAMAGE.
                     39:  */
                     40:
                     41: /*
                     42:  * Copyright (c) 1996 Charles M. Hannum.  All rights reserved.
                     43:  * Copyright (c) 1996 Jason R. Thorpe.  All rights reserved.
                     44:  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
                     45:  *
                     46:  * Redistribution and use in source and binary forms, with or without
                     47:  * modification, are permitted provided that the following conditions
                     48:  * are met:
                     49:  * 1. Redistributions of source code must retain the above copyright
                     50:  *    notice, this list of conditions and the following disclaimer.
                     51:  * 2. Redistributions in binary form must reproduce the above copyright
                     52:  *    notice, this list of conditions and the following disclaimer in the
                     53:  *    documentation and/or other materials provided with the distribution.
                     54:  * 3. All advertising materials mentioning features or use of this software
                     55:  *    must display the following acknowledgement:
                     56:  *     This product includes software developed by Christopher G. Demetriou
                     57:  *     for the NetBSD Project.
                     58:  * 4. The name of the author may not be used to endorse or promote products
                     59:  *    derived from this software without specific prior written permission
                     60:  *
                     61:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     62:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     63:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     64:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     65:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     66:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     67:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     68:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     69:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     70:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     71:  */
                     72:
                     73: #ifndef _X86_BUS_H_
                     74: #define _X86_BUS_H_
                     75:
                     76: #include <machine/pio.h>
                     77:
                     78: /*
                     79:  * Values for the x86 bus space tag, not to be used directly by MI code.
                     80:  */
                     81: #define        X86_BUS_SPACE_IO        0       /* space is i/o space */
                     82: #define X86_BUS_SPACE_MEM      1       /* space is mem space */
                     83:
                     84: /*
                     85:  * Bus address and size types
                     86:  */
                     87: typedef u_long bus_addr_t;
                     88: typedef u_long bus_size_t;
                     89:
                     90: /*
                     91:  * Access methods for bus resources and address space.
                     92:  */
                     93: typedef        int bus_space_tag_t;
                     94: typedef        u_long bus_space_handle_t;
                     95:
                     96: #define        bus_space_map(t, a, s, f, hp)   x86_memio_map((t),(a),(s),(f),(hp))
                     97: #define        bus_space_unmap(t, h, s)        x86_memio_unmap((t),(h),(s))
                     98: #define bus_space_subregion(t, h, o, s, nhp)   \
                     99:     x86_memio_subregion((t), (h), (o), (s), (nhp))
                    100:
                    101: int    x86_memio_map(bus_space_tag_t t, bus_addr_t addr,
                    102:     bus_size_t size, int flags, bus_space_handle_t *bshp);
                    103: /* like map, but without extent map checking/allocation */
                    104: int    _x86_memio_map(bus_space_tag_t t, bus_addr_t addr,
                    105:     bus_size_t size, int flags, bus_space_handle_t *bshp);
                    106:
                    107: #define        bus_space_alloc(t,beg,end,sz,align,bound,flag,addrp,h) \
                    108:     x86_memio_alloc((t),(beg),(end),(sz),(align),(bound),(flag),(addrp),(h))
                    109: int    x86_memio_alloc(bus_space_tag_t t, bus_addr_t rstart,
                    110:            bus_addr_t rend, bus_size_t size, bus_size_t align,
                    111:            bus_size_t boundary, int flags, bus_addr_t *addrp,
                    112:            bus_space_handle_t *bshp);
                    113: #define        bus_space_free(t,h,z)   x86_memio_free((t),(h),(z))
                    114: void   x86_memio_free(bus_space_tag_t t, bus_space_handle_t bsh,
                    115:            bus_size_t size);
                    116:
                    117: /*
                    118:  *      int bus_space_unmap(bus_space_tag_t t,
                    119:  *          bus_space_handle_t bsh, bus_size_t size);
                    120:  *
                    121:  * Unmap a region of bus space.
                    122:  */
                    123:
                    124: void   x86_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
                    125:            bus_size_t size);
                    126: void   _x86_memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
                    127:            bus_size_t size, bus_addr_t *);
                    128:
                    129: /* like bus_space_map(), but without extent map checking/allocation */
                    130: int    _bus_space_map(bus_space_tag_t t, bus_addr_t addr,
                    131:            bus_size_t size, int cacheable, bus_space_handle_t *bshp);
                    132:
                    133: /*
                    134:  *      int bus_space_subregion(bus_space_tag_t t,
                    135:  *          bus_space_handle_t bsh, bus_size_t offset, bus_size_t size,
                    136:  *          bus_space_handle_t *nbshp);
                    137:  *
                    138:  * Get a new handle for a subregion of an already-mapped area of bus space.
                    139:  */
                    140:
                    141: int    x86_memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh,
                    142:            bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp);
                    143:
                    144: /*
                    145:  *     u_intN_t bus_space_read_N(bus_space_tag_t tag,
                    146:  *         bus_space_handle_t bsh, bus_size_t offset);
                    147:  *
                    148:  * Read a 1, 2, 4, or 8 byte quantity from bus space
                    149:  * described by tag/handle/offset.
                    150:  */
                    151:
                    152: #define        bus_space_read_1(t, h, o)                                       \
                    153:        ((t) == X86_BUS_SPACE_IO ? (inb((h) + (o))) :                   \
                    154:            (*(volatile u_int8_t *)((h) + (o))))
                    155:
                    156: #define        bus_space_read_2(t, h, o)                                       \
                    157:        ((t) == X86_BUS_SPACE_IO ? (inw((h) + (o))) :                   \
                    158:            (*(volatile u_int16_t *)((h) + (o))))
                    159:
                    160: #define        bus_space_read_4(t, h, o)                                       \
                    161:        ((t) == X86_BUS_SPACE_IO ? (inl((h) + (o))) :                   \
                    162:            (*(volatile u_int32_t *)((h) + (o))))
                    163:
                    164: #if 0  /* Cause a link error for bus_space_read_8 */
                    165: #define        bus_space_read_8(t, h, o)       !!! bus_space_read_8 unimplemented !!!
                    166: #endif
                    167:
                    168: /*
                    169:  *     void bus_space_read_multi_N(bus_space_tag_t tag,
                    170:  *         bus_space_handle_t bsh, bus_size_t offset,
                    171:  *         u_intN_t *addr, size_t count);
                    172:  *
                    173:  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
                    174:  * described by tag/handle/offset and copy into buffer provided.
                    175:  */
                    176:
                    177: #define        bus_space_read_multi_1(t, h, o, ptr, cnt)                       \
                    178: do {                                                                   \
                    179:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    180:                insb((h) + (o), (ptr), (cnt));                          \
                    181:        } else {                                                        \
                    182:                void *dummy1;                                           \
                    183:                int dummy2;                                             \
                    184:                void *dummy3;                                           \
                    185:                int __x;                                                \
                    186:                __asm __volatile("                                      \
                    187:                        cld                                     ;       \
                    188:                1:      movb (%2),%%al                          ;       \
                    189:                        stosb                                   ;       \
                    190:                        loop 1b"                                :       \
                    191:                    "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
                    192:                    "0" ((ptr)), "1" ((cnt)), "2" ((h) + (o))       :   \
                    193:                    "memory");                                          \
                    194:        }                                                               \
                    195: } while (/* CONSTCOND */ 0)
                    196:
                    197: #define        bus_space_read_multi_2(t, h, o, ptr, cnt)                       \
                    198: do {                                                                   \
                    199:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    200:                insw((h) + (o), (ptr), (cnt));                          \
                    201:        } else {                                                        \
                    202:                void *dummy1;                                           \
                    203:                int dummy2;                                             \
                    204:                void *dummy3;                                           \
                    205:                int __x;                                                \
                    206:                __asm __volatile("                                      \
                    207:                        cld                                     ;       \
                    208:                1:      movw (%2),%%ax                          ;       \
                    209:                        stosw                                   ;       \
                    210:                        loop 1b"                                :       \
                    211:                    "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
                    212:                    "0" ((ptr)), "1" ((cnt)), "2" ((h) + (o))       :   \
                    213:                    "memory");                                          \
                    214:        }                                                               \
                    215: } while (/* CONSTCOND */ 0)
                    216:
                    217: #define        bus_space_read_multi_4(t, h, o, ptr, cnt)                       \
                    218: do {                                                                   \
                    219:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    220:                insl((h) + (o), (ptr), (cnt));                          \
                    221:        } else {                                                        \
                    222:                void *dummy1;                                           \
                    223:                int dummy2;                                             \
                    224:                void *dummy3;                                           \
                    225:                int __x;                                                \
                    226:                __asm __volatile("                                      \
                    227:                        cld                                     ;       \
                    228:                1:      movl (%2),%%eax                         ;       \
                    229:                        stosl                                   ;       \
                    230:                        loop 1b"                                :       \
                    231:                    "=D" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
                    232:                    "0" ((ptr)), "1" ((cnt)), "2" ((h) + (o))       :       \
                    233:                    "memory");                                          \
                    234:        }                                                               \
                    235: } while (/* CONSTCOND */ 0)
                    236:
                    237: #if 0  /* Cause a link error for bus_space_read_multi_8 */
                    238: #define        bus_space_read_multi_8  !!! bus_space_read_multi_8 unimplemented !!!
                    239: #endif
                    240:
                    241: /*
                    242:  *     void bus_space_read_raw_multi_N(bus_space_tag_t tag,
                    243:  *         bus_space_handle_t bsh, bus_size_t offset,
                    244:  *         u_int8_t *addr, size_t count);
                    245:  *
                    246:  * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
                    247:  * described by tag/handle/offset and copy into buffer provided.  The buffer
                    248:  * must have proper alignment for the N byte wide entities.  Furthermore
                    249:  * possible byte-swapping should be done by these functions.
                    250:  */
                    251:
                    252: #define        bus_space_read_raw_multi_2(t, h, o, a, c) \
                    253:     bus_space_read_multi_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1)
                    254: #define        bus_space_read_raw_multi_4(t, h, o, a, c) \
                    255:     bus_space_read_multi_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2)
                    256:
                    257: #if 0  /* Cause a link error for bus_space_read_raw_multi_8 */
                    258: #define        bus_space_read_raw_multi_8 \
                    259:     !!! bus_space_read_raw_multi_8 unimplemented !!!
                    260: #endif
                    261:
                    262: /*
                    263:  *     void bus_space_read_region_N(bus_space_tag_t tag,
                    264:  *         bus_space_handle_t bsh, bus_size_t offset,
                    265:  *         u_intN_t *addr, size_t count);
                    266:  *
                    267:  * Read `count' 1, 2, 4, or 8 byte quantities from bus space
                    268:  * described by tag/handle and starting at `offset' and copy into
                    269:  * buffer provided.
                    270:  */
                    271:
                    272: #define        bus_space_read_region_1(t, h, o, ptr, cnt)                      \
                    273: do {                                                                   \
                    274:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    275:                int dummy1;                                             \
                    276:                void *dummy2;                                           \
                    277:                int dummy3;                                             \
                    278:                int __x;                                                \
                    279:                __asm __volatile("                                      \
                    280:                        cld                                     ;       \
                    281:                1:      inb %w1,%%al                            ;       \
                    282:                        stosb                                   ;       \
                    283:                        incl %1                                 ;       \
                    284:                        loop 1b"                                :       \
                    285:                    "=&a" (__x), "=d" (dummy1), "=D" (dummy2),          \
                    286:                    "=c" (dummy3)                               :       \
                    287:                    "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
                    288:                    "memory");                                          \
                    289:        } else {                                                        \
                    290:                int dummy1;                                             \
                    291:                void *dummy2;                                           \
                    292:                int dummy3;                                             \
                    293:                __asm __volatile("                                      \
                    294:                        cld                                     ;       \
                    295:                        repne                                   ;       \
                    296:                        movsb"                                  :       \
                    297:                    "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) :       \
                    298:                    "0" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
                    299:                    "memory");                                          \
                    300:        }                                                               \
                    301: } while (/* CONSTCOND */ 0)
                    302:
                    303: #define        bus_space_read_region_2(t, h, o, ptr, cnt)                      \
                    304: do {                                                                   \
                    305:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    306:                int dummy1;                                             \
                    307:                void *dummy2;                                           \
                    308:                int dummy3;                                             \
                    309:                int __x;                                                \
                    310:                __asm __volatile("                                      \
                    311:                        cld                                     ;       \
                    312:                1:      inw %w1,%%ax                            ;       \
                    313:                        stosw                                   ;       \
                    314:                        addl $2,%1                              ;       \
                    315:                        loop 1b"                                :       \
                    316:                    "=&a" (__x), "=d" (dummy1), "=D" (dummy2),          \
                    317:                    "=c" (dummy3)                               :       \
                    318:                    "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
                    319:                    "memory");                                          \
                    320:        } else {                                                        \
                    321:                int dummy1;                                             \
                    322:                void *dummy2;                                           \
                    323:                int dummy3;                                             \
                    324:                __asm __volatile("                                      \
                    325:                        cld                                     ;       \
                    326:                        repne                                   ;       \
                    327:                        movsw"                                  :       \
                    328:                    "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) :       \
                    329:                    "0" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
                    330:                    "memory");                                          \
                    331:        }                                                               \
                    332: } while (/* CONSTCOND */ 0)
                    333:
                    334: #define        bus_space_read_region_4(t, h, o, ptr, cnt)                      \
                    335: do {                                                                   \
                    336:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    337:                int dummy1;                                             \
                    338:                void *dummy2;                                           \
                    339:                int dummy3;                                             \
                    340:                int __x;                                                \
                    341:                __asm __volatile("                                      \
                    342:                        cld                                     ;       \
                    343:                1:      inl %w1,%%eax                           ;       \
                    344:                        stosl                                   ;       \
                    345:                        addl $4,%1                              ;       \
                    346:                        loop 1b"                                :       \
                    347:                    "=&a" (__x), "=d" (dummy1), "=D" (dummy2),          \
                    348:                    "=c" (dummy3)                               :       \
                    349:                    "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
                    350:                    "memory");                                          \
                    351:        } else {                                                        \
                    352:                int dummy1;                                             \
                    353:                void *dummy2;                                           \
                    354:                int dummy3;                                             \
                    355:                __asm __volatile("                                      \
                    356:                        cld                                     ;       \
                    357:                        repne                                   ;       \
                    358:                        movsl"                                  :       \
                    359:                    "=S" (dummy1), "=D" (dummy2), "=c" (dummy3) :       \
                    360:                    "0" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
                    361:                    "memory");                                          \
                    362:        }                                                               \
                    363: } while (/* CONSTCOND */ 0)
                    364:
                    365: #define bus_space_read_region_stream_1 bus_space_read_region_1
                    366: #if 0  /* Cause a link error for bus_space_read_region_8 */
                    367: #define        bus_space_read_region_8 !!! bus_space_read_region_8 unimplemented !!!
                    368: #endif
                    369:
                    370: /*
                    371:  *     void bus_space_read_raw_region_N(bus_space_tag_t tag,
                    372:  *         bus_space_handle_t bsh, bus_size_t offset,
                    373:  *         u_int8_t *addr, size_t count);
                    374:  *
                    375:  * Read `count' bytes in 2, 4 or 8 byte wide quantities from bus space
                    376:  * described by tag/handle and starting at `offset' and copy into
                    377:  * buffer provided.  The buffer must have proper alignment for the N byte
                    378:  * wide entities.  Furthermore possible byte-swapping should be done by
                    379:  * these functions.
                    380:  */
                    381:
                    382: #define        bus_space_read_raw_region_2(t, h, o, a, c) \
                    383:     bus_space_read_region_2((t), (h), (o), (u_int16_t *)(a), (c) >> 1)
                    384: #define        bus_space_read_raw_region_4(t, h, o, a, c) \
                    385:     bus_space_read_region_4((t), (h), (o), (u_int32_t *)(a), (c) >> 2)
                    386:
                    387: #if 0  /* Cause a link error for bus_space_read_raw_region_8 */
                    388: #define        bus_space_read_raw_region_8 \
                    389:     !!! bus_space_read_raw_region_8 unimplemented !!!
                    390: #endif
                    391:
                    392: /*
                    393:  *     void bus_space_write_N(bus_space_tag_t tag,
                    394:  *         bus_space_handle_t bsh, bus_size_t offset,
                    395:  *         u_intN_t value);
                    396:  *
                    397:  * Write the 1, 2, 4, or 8 byte value `value' to bus space
                    398:  * described by tag/handle/offset.
                    399:  */
                    400:
                    401: #define        bus_space_write_1(t, h, o, v)   do {                            \
                    402:        if ((t) == X86_BUS_SPACE_IO)                                    \
                    403:                outb((h) + (o), (v));                                   \
                    404:        else                                                            \
                    405:                ((void)(*(volatile u_int8_t *)((h) + (o)) = (v)));      \
                    406: } while (0)
                    407:
                    408: #define        bus_space_write_2(t, h, o, v)   do {                            \
                    409:        if ((t) == X86_BUS_SPACE_IO)                                    \
                    410:                outw((h) + (o), (v));                                   \
                    411:        else                                                            \
                    412:                ((void)(*(volatile u_int16_t *)((h) + (o)) = (v)));     \
                    413: } while (0)
                    414:
                    415: #define        bus_space_write_4(t, h, o, v)   do {                            \
                    416:        if ((t) == X86_BUS_SPACE_IO)                                    \
                    417:                outl((h) + (o), (v));                                   \
                    418:        else                                                            \
                    419:                ((void)(*(volatile u_int32_t *)((h) + (o)) = (v)));     \
                    420: } while (0)
                    421:
                    422: #if 0  /* Cause a link error for bus_space_write_8 */
                    423: #define        bus_space_write_8       !!! bus_space_write_8 not implemented !!!
                    424: #endif
                    425:
                    426: /*
                    427:  *     void bus_space_write_multi_N(bus_space_tag_t tag,
                    428:  *         bus_space_handle_t bsh, bus_size_t offset,
                    429:  *         const u_intN_t *addr, size_t count);
                    430:  *
                    431:  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer
                    432:  * provided to bus space described by tag/handle/offset.
                    433:  */
                    434:
                    435: #define        bus_space_write_multi_1(t, h, o, ptr, cnt)                      \
                    436: do {                                                                   \
                    437:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    438:                outsb((h) + (o), (ptr), (cnt));                         \
                    439:        } else {                                                        \
                    440:                void *dummy1;                                           \
                    441:                int dummy2;                                             \
                    442:                void *dummy3;                                           \
                    443:                int __x;                                                \
                    444:                __asm __volatile("                                      \
                    445:                        cld                                     ;       \
                    446:                1:      lodsb                                   ;       \
                    447:                        movb %%al,(%2)                          ;       \
                    448:                        loop 1b"                                :       \
                    449:                    "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
                    450:                    "0" ((ptr)), "1" ((cnt)), "2" ((h) + (o)));         \
                    451:        }                                                               \
                    452: } while (/* CONSTCOND */ 0)
                    453:
                    454: #define bus_space_write_multi_2(t, h, o, ptr, cnt)                     \
                    455: do {                                                                   \
                    456:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    457:                outsw((h) + (o), (ptr), (cnt));                         \
                    458:        } else {                                                        \
                    459:                void *dummy1;                                           \
                    460:                int dummy2;                                             \
                    461:                void *dummy3;                                           \
                    462:                int __x;                                                \
                    463:                __asm __volatile("                                      \
                    464:                        cld                                     ;       \
                    465:                1:      lodsw                                   ;       \
                    466:                        movw %%ax,(%2)                          ;       \
                    467:                        loop 1b"                                :       \
                    468:                    "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
                    469:                    "0" ((ptr)), "1" ((cnt)), "2" ((h) + (o)));         \
                    470:        }                                                               \
                    471: } while (/* CONSTCOND */ 0)
                    472:
                    473: #define bus_space_write_multi_4(t, h, o, ptr, cnt)                     \
                    474: do {                                                                   \
                    475:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    476:                outsl((h) + (o), (ptr), (cnt));                         \
                    477:        } else {                                                        \
                    478:                void *dummy1;                                           \
                    479:                int dummy2;                                             \
                    480:                void *dummy3;                                           \
                    481:                int __x;                                                \
                    482:                __asm __volatile("                                      \
                    483:                        cld                                     ;       \
                    484:                1:      lodsl                                   ;       \
                    485:                        movl %%eax,(%2)                         ;       \
                    486:                        loop 1b"                                :       \
                    487:                    "=S" (dummy1), "=c" (dummy2), "=r" (dummy3), "=&a" (__x) : \
                    488:                    "0" ((ptr)), "1" ((cnt)), "2" ((h) + (o)));         \
                    489:        }                                                               \
                    490: } while (/* CONSTCOND */ 0)
                    491:
                    492: #if 0  /* Cause a link error for bus_space_write_multi_8 */
                    493: #define        bus_space_write_multi_8(t, h, o, a, c)                          \
                    494:                        !!! bus_space_write_multi_8 unimplemented !!!
                    495: #endif
                    496:
                    497: /*
                    498:  *     void bus_space_write_raw_multi_N(bus_space_tag_t tag,
                    499:  *         bus_space_handle_t bsh, bus_size_t offset,
                    500:  *         const u_int8_t *addr, size_t count);
                    501:  *
                    502:  * Write `count' bytes in 2, 4 or 8 byte wide quantities from the buffer
                    503:  * provided to bus space described by tag/handle/offset.  The buffer
                    504:  * must have proper alignment for the N byte wide entities.  Furthermore
                    505:  * possible byte-swapping should be done by these functions.
                    506:  */
                    507:
                    508: #define        bus_space_write_raw_multi_2(t, h, o, a, c) \
                    509:     bus_space_write_multi_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1)
                    510: #define        bus_space_write_raw_multi_4(t, h, o, a, c) \
                    511:     bus_space_write_multi_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2)
                    512:
                    513: #if 0  /* Cause a link error for bus_space_write_raw_multi_8 */
                    514: #define        bus_space_write_raw_multi_8 \
                    515:     !!! bus_space_write_raw_multi_8 unimplemented !!!
                    516: #endif
                    517:
                    518: /*
                    519:  *     void bus_space_write_region_N(bus_space_tag_t tag,
                    520:  *         bus_space_handle_t bsh, bus_size_t offset,
                    521:  *         const u_intN_t *addr, size_t count);
                    522:  *
                    523:  * Write `count' 1, 2, 4, or 8 byte quantities from the buffer provided
                    524:  * to bus space described by tag/handle starting at `offset'.
                    525:  */
                    526:
                    527: #define        bus_space_write_region_1(t, h, o, ptr, cnt)                     \
                    528: do {                                                                   \
                    529:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    530:                int dummy1;                                             \
                    531:                void *dummy2;                                           \
                    532:                int dummy3;                                             \
                    533:                int __x;                                                \
                    534:                __asm __volatile("                                      \
                    535:                        cld                                     ;       \
                    536:                1:      lodsb                                   ;       \
                    537:                        outb %%al,%w1                           ;       \
                    538:                        incl %1                                 ;       \
                    539:                        loop 1b"                                :       \
                    540:                    "=&a" (__x), "=d" (dummy1), "=S" (dummy2),          \
                    541:                    "=c" (dummy3)                               :       \
                    542:                    "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
                    543:                    "memory");                                          \
                    544:        } else {                                                        \
                    545:                int dummy1;                                             \
                    546:                void *dummy2;                                           \
                    547:                int dummy3;                                             \
                    548:                __asm __volatile("                                      \
                    549:                        cld                                     ;       \
                    550:                        repne                                   ;       \
                    551:                        movsb"                                  :       \
                    552:                    "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) :       \
                    553:                    "0" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
                    554:                    "memory");                                          \
                    555:        }                                                               \
                    556: } while (/* CONSTCOND */ 0)
                    557:
                    558: #define        bus_space_write_region_2(t, h, o, ptr, cnt)                     \
                    559: do {                                                                   \
                    560:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    561:                int dummy1;                                             \
                    562:                void *dummy2;                                           \
                    563:                int dummy3;                                             \
                    564:                int __x;                                                \
                    565:                __asm __volatile("                                      \
                    566:                        cld                                     ;       \
                    567:                1:      lodsw                                   ;       \
                    568:                        outw %%ax,%w1                           ;       \
                    569:                        addl $2,%1                              ;       \
                    570:                        loop 1b"                                :       \
                    571:                    "=&a" (__x), "=d" (dummy1), "=S" (dummy2),          \
                    572:                    "=c" (dummy3)                               :       \
                    573:                    "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
                    574:                    "memory");                                          \
                    575:        } else {                                                        \
                    576:                int dummy1;                                             \
                    577:                void *dummy2;                                           \
                    578:                int dummy3;                                             \
                    579:                __asm __volatile("                                      \
                    580:                        cld                                     ;       \
                    581:                        repne                                   ;       \
                    582:                        movsw"                                  :       \
                    583:                    "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) :       \
                    584:                    "0" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
                    585:                    "memory");                                          \
                    586:        }                                                               \
                    587: } while (/* CONSTCOND */ 0)
                    588:
                    589: #define        bus_space_write_region_4(t, h, o, ptr, cnt)                     \
                    590: do {                                                                   \
                    591:        if ((t) == X86_BUS_SPACE_IO) {                                  \
                    592:                int dummy1;                                             \
                    593:                void *dummy2;                                           \
                    594:                int dummy3;                                             \
                    595:                int __x;                                                \
                    596:                __asm __volatile("                                      \
                    597:                        cld                                     ;       \
                    598:                1:      lodsl                                   ;       \
                    599:                        outl %%eax,%w1                          ;       \
                    600:                        addl $4,%1                              ;       \
                    601:                        loop 1b"                                :       \
                    602:                    "=&a" (__x), "=d" (dummy1), "=S" (dummy2),          \
                    603:                    "=c" (dummy3)                               :       \
                    604:                    "1" ((h) + (o)), "2" ((ptr)), "3" ((cnt))   :       \
                    605:                    "memory");                                          \
                    606:        } else {                                                        \
                    607:                int dummy1;                                             \
                    608:                void *dummy2;                                           \
                    609:                int dummy3;                                             \
                    610:                __asm __volatile("                                      \
                    611:                        cld                                     ;       \
                    612:                        repne                                   ;       \
                    613:                        movsl"                                  :       \
                    614:                    "=D" (dummy1), "=S" (dummy2), "=c" (dummy3) :       \
                    615:                    "0" ((h) + (o)), "1" ((ptr)), "2" ((cnt))   :       \
                    616:                    "memory");                                          \
                    617:        }                                                               \
                    618: } while (/* CONSTCOND */ 0)
                    619:
                    620: #if 0  /* Cause a link error for bus_space_write_region_8 */
                    621: #define        bus_space_write_region_8                                        \
                    622:                        !!! bus_space_write_region_8 unimplemented !!!
                    623: #endif
                    624:
                    625: /*
                    626:  *     void bus_space_write_raw_region_N(bus_space_tag_t tag,
                    627:  *         bus_space_handle_t bsh, bus_size_t offset,
                    628:  *         const u_int8_t *addr, size_t count);
                    629:  *
                    630:  * Write `count' bytes in 2, 4 or 8 byte wide quantities to bus space
                    631:  * described by tag/handle and starting at `offset' from the
                    632:  * buffer provided.  The buffer must have proper alignment for the N byte
                    633:  * wide entities.  Furthermore possible byte-swapping should be done by
                    634:  * these functions.
                    635:  */
                    636:
                    637: #define        bus_space_write_raw_region_2(t, h, o, a, c) \
                    638:     bus_space_write_region_2((t), (h), (o), (const u_int16_t *)(a), (c) >> 1)
                    639: #define        bus_space_write_raw_region_4(t, h, o, a, c) \
                    640:     bus_space_write_region_4((t), (h), (o), (const u_int32_t *)(a), (c) >> 2)
                    641:
                    642: #if 0  /* Cause a link error for bus_space_write_raw_region_8 */
                    643: #define        bus_space_write_raw_region_8 \
                    644:     !!! bus_space_write_raw_region_8 unimplemented !!!
                    645: #endif
                    646:
                    647: /*
                    648:  *     void bus_space_set_multi_N(bus_space_tag_t tag,
                    649:  *         bus_space_handle_t bsh, bus_size_t offset,
                    650:  *         u_intN_t val, size_t count);
                    651:  *
                    652:  * Write the 1, 2, 4, or 8 byte value `val' to bus space described
                    653:  * by tag/handle/offset `count' times.
                    654:  */
                    655:
                    656: static __inline void x86_memio_set_multi_1(bus_space_tag_t,
                    657:        bus_space_handle_t, bus_size_t, u_int8_t, size_t);
                    658: static __inline void x86_memio_set_multi_2(bus_space_tag_t,
                    659:        bus_space_handle_t, bus_size_t, u_int16_t, size_t);
                    660: static __inline void x86_memio_set_multi_4(bus_space_tag_t,
                    661:        bus_space_handle_t, bus_size_t, u_int32_t, size_t);
                    662:
                    663: #define        bus_space_set_multi_1(t, h, o, v, c)                            \
                    664:        x86_memio_set_multi_1((t), (h), (o), (v), (c))
                    665:
                    666: #define        bus_space_set_multi_2(t, h, o, v, c)                            \
                    667:        x86_memio_set_multi_2((t), (h), (o), (v), (c))
                    668:
                    669: #define        bus_space_set_multi_4(t, h, o, v, c)                            \
                    670:        x86_memio_set_multi_4((t), (h), (o), (v), (c))
                    671:
                    672: static __inline void
                    673: x86_memio_set_multi_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
                    674:     u_int8_t v, size_t c)
                    675: {
                    676:        bus_addr_t addr = h + o;
                    677:
                    678:        if (t == X86_BUS_SPACE_IO)
                    679:                while (c--)
                    680:                        outb(addr, v);
                    681:        else
                    682:                while (c--)
                    683:                        *(volatile u_int8_t *)(addr) = v;
                    684: }
                    685:
                    686: static __inline void
                    687: x86_memio_set_multi_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
                    688:     u_int16_t v, size_t c)
                    689: {
                    690:        bus_addr_t addr = h + o;
                    691:
                    692:        if (t == X86_BUS_SPACE_IO)
                    693:                while (c--)
                    694:                        outw(addr, v);
                    695:        else
                    696:                while (c--)
                    697:                        *(volatile u_int16_t *)(addr) = v;
                    698: }
                    699:
                    700: static __inline void
                    701: x86_memio_set_multi_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
                    702:     u_int32_t v, size_t c)
                    703: {
                    704:        bus_addr_t addr = h + o;
                    705:
                    706:        if (t == X86_BUS_SPACE_IO)
                    707:                while (c--)
                    708:                        outl(addr, v);
                    709:        else
                    710:                while (c--)
                    711:                        *(volatile u_int32_t *)(addr) = v;
                    712: }
                    713:
                    714: #if 0  /* Cause a link error for bus_space_set_multi_8 */
                    715: #define        bus_space_set_multi_8                                   \
                    716:                        !!! bus_space_set_multi_8 unimplemented !!!
                    717: #endif
                    718:
                    719: /*
                    720:  *     void bus_space_set_region_N(bus_space_tag_t tag,
                    721:  *         bus_space_handle_t bsh, bus_size_t offset,
                    722:  *         u_intN_t val, size_t count);
                    723:  *
                    724:  * Write `count' 1, 2, 4, or 8 byte value `val' to bus space described
                    725:  * by tag/handle starting at `offset'.
                    726:  */
                    727:
                    728: static __inline void x86_memio_set_region_1(bus_space_tag_t,
                    729:        bus_space_handle_t, bus_size_t, u_int8_t, size_t);
                    730: static __inline void x86_memio_set_region_2(bus_space_tag_t,
                    731:        bus_space_handle_t, bus_size_t, u_int16_t, size_t);
                    732: static __inline void x86_memio_set_region_4(bus_space_tag_t,
                    733:        bus_space_handle_t, bus_size_t, u_int32_t, size_t);
                    734:
                    735: #define        bus_space_set_region_1(t, h, o, v, c)                           \
                    736:        x86_memio_set_region_1((t), (h), (o), (v), (c))
                    737:
                    738: #define        bus_space_set_region_2(t, h, o, v, c)                           \
                    739:        x86_memio_set_region_2((t), (h), (o), (v), (c))
                    740:
                    741: #define        bus_space_set_region_4(t, h, o, v, c)                           \
                    742:        x86_memio_set_region_4((t), (h), (o), (v), (c))
                    743:
                    744: static __inline void
                    745: x86_memio_set_region_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
                    746:     u_int8_t v, size_t c)
                    747: {
                    748:        bus_addr_t addr = h + o;
                    749:
                    750:        if (t == X86_BUS_SPACE_IO)
                    751:                for (; c != 0; c--, addr++)
                    752:                        outb(addr, v);
                    753:        else
                    754:                for (; c != 0; c--, addr++)
                    755:                        *(volatile u_int8_t *)(addr) = v;
                    756: }
                    757:
                    758: static __inline void
                    759: x86_memio_set_region_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
                    760:     u_int16_t v, size_t c)
                    761: {
                    762:        bus_addr_t addr = h + o;
                    763:
                    764:        if (t == X86_BUS_SPACE_IO)
                    765:                for (; c != 0; c--, addr += 2)
                    766:                        outw(addr, v);
                    767:        else
                    768:                for (; c != 0; c--, addr += 2)
                    769:                        *(volatile u_int16_t *)(addr) = v;
                    770: }
                    771:
                    772: static __inline void
                    773: x86_memio_set_region_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
                    774:     u_int32_t v, size_t c)
                    775: {
                    776:        bus_addr_t addr = h + o;
                    777:
                    778:        if (t == X86_BUS_SPACE_IO)
                    779:                for (; c != 0; c--, addr += 4)
                    780:                        outl(addr, v);
                    781:        else
                    782:                for (; c != 0; c--, addr += 4)
                    783:                        *(volatile u_int32_t *)(addr) = v;
                    784: }
                    785:
                    786: #if 0  /* Cause a link error for bus_space_set_region_8 */
                    787: #define        bus_space_set_region_8                                  \
                    788:                        !!! bus_space_set_region_8 unimplemented !!!
                    789: #endif
                    790:
                    791: /*
                    792:  *     void bus_space_copy_N(bus_space_tag_t tag,
                    793:  *         bus_space_handle_t bsh1, bus_size_t off1,
                    794:  *         bus_space_handle_t bsh2, bus_size_t off2,
                    795:  *         size_t count);
                    796:  *
                    797:  * Copy `count' 1, 2, 4, or 8 byte values from bus space starting
                    798:  * at tag/bsh1/off1 to bus space starting at tag/bsh2/off2.
                    799:  */
                    800:
                    801: #define bus_space_copy_1 bus_space_copy_region_1
                    802: #define bus_space_copy_2 bus_space_copy_region_2
                    803: #define bus_space_copy_4 bus_space_copy_region_4
                    804: #define bus_space_copy_8 bus_space_copy_region_8
                    805:
                    806: static __inline void x86_memio_copy_region_1(bus_space_tag_t,
                    807:        bus_space_handle_t, bus_size_t, bus_space_handle_t,
                    808:        bus_size_t, size_t);
                    809: static __inline void x86_memio_copy_region_2(bus_space_tag_t,
                    810:        bus_space_handle_t, bus_size_t, bus_space_handle_t,
                    811:        bus_size_t, size_t);
                    812: static __inline void x86_memio_copy_region_4(bus_space_tag_t,
                    813:        bus_space_handle_t, bus_size_t, bus_space_handle_t,
                    814:        bus_size_t, size_t);
                    815:
                    816: #define        bus_space_copy_region_1(t, h1, o1, h2, o2, c)                   \
                    817:        x86_memio_copy_region_1((t), (h1), (o1), (h2), (o2), (c))
                    818:
                    819: #define        bus_space_copy_region_2(t, h1, o1, h2, o2, c)                   \
                    820:        x86_memio_copy_region_2((t), (h1), (o1), (h2), (o2), (c))
                    821:
                    822: #define        bus_space_copy_region_4(t, h1, o1, h2, o2, c)                   \
                    823:        x86_memio_copy_region_4((t), (h1), (o1), (h2), (o2), (c))
                    824:
                    825: static __inline void
                    826: x86_memio_copy_region_1(bus_space_tag_t t,
                    827:     bus_space_handle_t h1, bus_size_t o1,
                    828:     bus_space_handle_t h2, bus_size_t o2, size_t c)
                    829: {
                    830:        bus_addr_t addr1 = h1 + o1;
                    831:        bus_addr_t addr2 = h2 + o2;
                    832:
                    833:        if (t == X86_BUS_SPACE_IO) {
                    834:                if (addr1 >= addr2) {
                    835:                        /* src after dest: copy forward */
                    836:                        for (; c != 0; c--, addr1++, addr2++)
                    837:                                outb(addr2, inb(addr1));
                    838:                } else {
                    839:                        /* dest after src: copy backwards */
                    840:                        for (addr1 += (c - 1), addr2 += (c - 1);
                    841:                            c != 0; c--, addr1--, addr2--)
                    842:                                outb(addr2, inb(addr1));
                    843:                }
                    844:        } else {
                    845:                if (addr1 >= addr2) {
                    846:                        /* src after dest: copy forward */
                    847:                        for (; c != 0; c--, addr1++, addr2++)
                    848:                                *(volatile u_int8_t *)(addr2) =
                    849:                                    *(volatile u_int8_t *)(addr1);
                    850:                } else {
                    851:                        /* dest after src: copy backwards */
                    852:                        for (addr1 += (c - 1), addr2 += (c - 1);
                    853:                            c != 0; c--, addr1--, addr2--)
                    854:                                *(volatile u_int8_t *)(addr2) =
                    855:                                    *(volatile u_int8_t *)(addr1);
                    856:                }
                    857:        }
                    858: }
                    859:
                    860: static __inline void
                    861: x86_memio_copy_region_2(bus_space_tag_t t,
                    862:     bus_space_handle_t h1, bus_size_t o1,
                    863:     bus_space_handle_t h2, bus_size_t o2, size_t c)
                    864: {
                    865:        bus_addr_t addr1 = h1 + o1;
                    866:        bus_addr_t addr2 = h2 + o2;
                    867:
                    868:        if (t == X86_BUS_SPACE_IO) {
                    869:                if (addr1 >= addr2) {
                    870:                        /* src after dest: copy forward */
                    871:                        for (; c != 0; c--, addr1 += 2, addr2 += 2)
                    872:                                outw(addr2, inw(addr1));
                    873:                } else {
                    874:                        /* dest after src: copy backwards */
                    875:                        for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
                    876:                            c != 0; c--, addr1 -= 2, addr2 -= 2)
                    877:                                outw(addr2, inw(addr1));
                    878:                }
                    879:        } else {
                    880:                if (addr1 >= addr2) {
                    881:                        /* src after dest: copy forward */
                    882:                        for (; c != 0; c--, addr1 += 2, addr2 += 2)
                    883:                                *(volatile u_int16_t *)(addr2) =
                    884:                                    *(volatile u_int16_t *)(addr1);
                    885:                } else {
                    886:                        /* dest after src: copy backwards */
                    887:                        for (addr1 += 2 * (c - 1), addr2 += 2 * (c - 1);
                    888:                            c != 0; c--, addr1 -= 2, addr2 -= 2)
                    889:                                *(volatile u_int16_t *)(addr2) =
                    890:                                    *(volatile u_int16_t *)(addr1);
                    891:                }
                    892:        }
                    893: }
                    894:
                    895: static __inline void
                    896: x86_memio_copy_region_4(bus_space_tag_t t,
                    897:     bus_space_handle_t h1, bus_size_t o1,
                    898:     bus_space_handle_t h2, bus_size_t o2, size_t c)
                    899: {
                    900:        bus_addr_t addr1 = h1 + o1;
                    901:        bus_addr_t addr2 = h2 + o2;
                    902:
                    903:        if (t == X86_BUS_SPACE_IO) {
                    904:                if (addr1 >= addr2) {
                    905:                        /* src after dest: copy forward */
                    906:                        for (; c != 0; c--, addr1 += 4, addr2 += 4)
                    907:                                outl(addr2, inl(addr1));
                    908:                } else {
                    909:                        /* dest after src: copy backwards */
                    910:                        for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
                    911:                            c != 0; c--, addr1 -= 4, addr2 -= 4)
                    912:                                outl(addr2, inl(addr1));
                    913:                }
                    914:        } else {
                    915:                if (addr1 >= addr2) {
                    916:                        /* src after dest: copy forward */
                    917:                        for (; c != 0; c--, addr1 += 4, addr2 += 4)
                    918:                                *(volatile u_int32_t *)(addr2) =
                    919:                                    *(volatile u_int32_t *)(addr1);
                    920:                } else {
                    921:                        /* dest after src: copy backwards */
                    922:                        for (addr1 += 4 * (c - 1), addr2 += 4 * (c - 1);
                    923:                            c != 0; c--, addr1 -= 4, addr2 -= 4)
                    924:                                *(volatile u_int32_t *)(addr2) =
                    925:                                    *(volatile u_int32_t *)(addr1);
                    926:                }
                    927:        }
                    928: }
                    929:
                    930: #if 0  /* Cause a link error for bus_space_copy_8 */
                    931: #define        bus_space_copy_8                                        \
                    932:                        !!! bus_space_copy_8 unimplemented !!!
                    933: #endif
                    934:
                    935: /*
                    936:  * Bus read/write barrier methods.
                    937:  */
                    938: #define        BUS_SPACE_BARRIER_READ  0x01            /* force read barrier */
                    939: #define        BUS_SPACE_BARRIER_WRITE 0x02            /* force write barrier */
                    940: /* Compatibility defines */
                    941: #define        BUS_BARRIER_READ        BUS_SPACE_BARRIER_READ
                    942: #define        BUS_BARRIER_WRITE       BUS_SPACE_BARRIER_WRITE
                    943:
                    944: static __inline void
                    945: bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t bsh,
                    946:     bus_size_t offset, bus_size_t len, int flags)
                    947: {
                    948:        if (flags == (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE))
                    949:                __asm __volatile("mfence");
                    950:        else if (flags == BUS_SPACE_BARRIER_WRITE)
                    951:                __asm __volatile("sfence");
                    952:        else
                    953:                __asm __volatile("lfence");
                    954: }
                    955:
                    956: /*
                    957:  * Flags used in various bus DMA methods.
                    958:  */
                    959: #define        BUS_DMA_WAITOK          0x000   /* safe to sleep (pseudo-flag) */
                    960: #define        BUS_DMA_NOWAIT          0x001   /* not safe to sleep */
                    961: #define        BUS_DMA_ALLOCNOW        0x002   /* perform resource allocation now */
                    962: #define        BUS_DMA_COHERENT        0x004   /* hint: map memory DMA coherent */
                    963: #define        BUS_DMA_BUS1            0x010   /* placeholders for bus functions... */
                    964: #define        BUS_DMA_BUS2            0x020
                    965: #define        BUS_DMA_BUS3            0x040
                    966: #define        BUS_DMA_24BIT           0x080   /* isadma map */
                    967: #define        BUS_DMA_STREAMING       0x100   /* hint: sequential, unidirectional */
                    968: #define        BUS_DMA_READ            0x200   /* mapping is device -> memory only */
                    969: #define        BUS_DMA_WRITE           0x400   /* mapping is memory -> device only */
                    970:
                    971: /* Forwards needed by prototypes below. */
                    972: struct mbuf;
                    973: struct proc;
                    974: struct uio;
                    975:
                    976: /*
                    977:  * Operations performed by bus_dmamap_sync().
                    978:  */
                    979: #define BUS_DMASYNC_PREREAD    0x01
                    980: #define BUS_DMASYNC_POSTREAD   0x02
                    981: #define BUS_DMASYNC_PREWRITE   0x04
                    982: #define BUS_DMASYNC_POSTWRITE  0x08
                    983:
                    984: typedef struct x86_bus_dma_tag         *bus_dma_tag_t;
                    985: typedef struct x86_bus_dmamap          *bus_dmamap_t;
                    986:
                    987: /*
                    988:  *     bus_dma_segment_t
                    989:  *
                    990:  *     Describes a single contiguous DMA transaction.  Values
                    991:  *     are suitable for programming into DMA registers.
                    992:  */
                    993: struct x86_bus_dma_segment {
                    994:        bus_addr_t      ds_addr;        /* DMA address */
                    995:        bus_size_t      ds_len;         /* length of transfer */
                    996: };
                    997: typedef struct x86_bus_dma_segment     bus_dma_segment_t;
                    998:
                    999: /*
                   1000:  *     bus_dma_tag_t
                   1001:  *
                   1002:  *     A machine-dependent opaque type describing the implementation of
                   1003:  *     DMA for a given bus.
                   1004:  */
                   1005:
                   1006: struct x86_bus_dma_tag {
                   1007:        void    *_cookie;               /* cookie used in the guts */
                   1008:
                   1009:        /*
                   1010:         * DMA mapping methods.
                   1011:         */
                   1012:        int     (*_dmamap_create)(bus_dma_tag_t, bus_size_t, int,
                   1013:                    bus_size_t, bus_size_t, int, bus_dmamap_t *);
                   1014:        void    (*_dmamap_destroy)(bus_dma_tag_t, bus_dmamap_t);
                   1015:        int     (*_dmamap_load)(bus_dma_tag_t, bus_dmamap_t, void *,
                   1016:                    bus_size_t, struct proc *, int);
                   1017:        int     (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dmamap_t,
                   1018:                    struct mbuf *, int);
                   1019:        int     (*_dmamap_load_uio)(bus_dma_tag_t, bus_dmamap_t,
                   1020:                    struct uio *, int);
                   1021:        int     (*_dmamap_load_raw)(bus_dma_tag_t, bus_dmamap_t,
                   1022:                    bus_dma_segment_t *, int, bus_size_t, int);
                   1023:        void    (*_dmamap_unload)(bus_dma_tag_t, bus_dmamap_t);
                   1024:        void    (*_dmamap_sync)(bus_dma_tag_t, bus_dmamap_t,
                   1025:                    bus_addr_t, bus_size_t, int);
                   1026:
                   1027:        /*
                   1028:         * DMA memory utility functions.
                   1029:         */
                   1030:        int     (*_dmamem_alloc)(bus_dma_tag_t, bus_size_t, bus_size_t,
                   1031:                    bus_size_t, bus_dma_segment_t *, int, int *, int);
                   1032:        void    (*_dmamem_free)(bus_dma_tag_t,
                   1033:                    bus_dma_segment_t *, int);
                   1034:        int     (*_dmamem_map)(bus_dma_tag_t, bus_dma_segment_t *,
                   1035:                    int, size_t, caddr_t *, int);
                   1036:        void    (*_dmamem_unmap)(bus_dma_tag_t, caddr_t, size_t);
                   1037:        paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_segment_t *,
                   1038:                    int, off_t, int, int);
                   1039: };
                   1040:
                   1041: #define        bus_dmamap_create(t, s, n, m, b, f, p)                  \
                   1042:        (*(t)->_dmamap_create)((t), (s), (n), (m), (b), (f), (p))
                   1043: #define        bus_dmamap_destroy(t, p)                                \
                   1044:        (*(t)->_dmamap_destroy)((t), (p))
                   1045: #define        bus_dmamap_load(t, m, b, s, p, f)                       \
                   1046:        (*(t)->_dmamap_load)((t), (m), (b), (s), (p), (f))
                   1047: #define        bus_dmamap_load_mbuf(t, m, b, f)                        \
                   1048:        (*(t)->_dmamap_load_mbuf)((t), (m), (b), (f))
                   1049: #define        bus_dmamap_load_uio(t, m, u, f)                         \
                   1050:        (*(t)->_dmamap_load_uio)((t), (m), (u), (f))
                   1051: #define        bus_dmamap_load_raw(t, m, sg, n, s, f)                  \
                   1052:        (*(t)->_dmamap_load_raw)((t), (m), (sg), (n), (s), (f))
                   1053: #define        bus_dmamap_unload(t, p)                                 \
                   1054:        (*(t)->_dmamap_unload)((t), (p))
                   1055: #define        bus_dmamap_sync(t, p, o, l, ops)                        \
                   1056:        (void)((t)->_dmamap_sync ?                              \
                   1057:            (*(t)->_dmamap_sync)((t), (p), (o), (l), (ops)) : (void)0)
                   1058:
                   1059: #define        bus_dmamem_alloc(t, s, a, b, sg, n, r, f)               \
                   1060:        (*(t)->_dmamem_alloc)((t), (s), (a), (b), (sg), (n), (r), (f))
                   1061: #define        bus_dmamem_free(t, sg, n)                               \
                   1062:        (*(t)->_dmamem_free)((t), (sg), (n))
                   1063: #define        bus_dmamem_map(t, sg, n, s, k, f)                       \
                   1064:        (*(t)->_dmamem_map)((t), (sg), (n), (s), (k), (f))
                   1065: #define        bus_dmamem_unmap(t, k, s)                               \
                   1066:        (*(t)->_dmamem_unmap)((t), (k), (s))
                   1067: #define        bus_dmamem_mmap(t, sg, n, o, p, f)                      \
                   1068:        (*(t)->_dmamem_mmap)((t), (sg), (n), (o), (p), (f))
                   1069:
                   1070: /*
                   1071:  *     bus_dmamap_t
                   1072:  *
                   1073:  *     Describes a DMA mapping.
                   1074:  */
                   1075: struct x86_bus_dmamap {
                   1076:        /*
                   1077:         * PRIVATE MEMBERS: not for use by machine-independent code.
                   1078:         */
                   1079:        bus_size_t      _dm_size;       /* largest DMA transfer mappable */
                   1080:        int             _dm_segcnt;     /* number of segs this map can map */
                   1081:        bus_size_t      _dm_maxsegsz;   /* largest possible segment */
                   1082:        bus_size_t      _dm_boundary;   /* don't cross this */
                   1083:        int             _dm_flags;      /* misc. flags */
                   1084:
                   1085:        void            *_dm_cookie;    /* cookie for bus-specific functions */
                   1086:
                   1087:        /*
                   1088:         * PUBLIC MEMBERS: these are used by machine-independent code.
                   1089:         */
                   1090:        bus_size_t      dm_mapsize;     /* size of the mapping */
                   1091:        int             dm_nsegs;       /* # valid segments in mapping */
                   1092:        bus_dma_segment_t dm_segs[1];   /* segments; variable length */
                   1093: };
                   1094:
                   1095: #ifdef _X86_BUS_DMA_PRIVATE
                   1096: int    _bus_dmamap_create(bus_dma_tag_t, bus_size_t, int, bus_size_t,
                   1097:            bus_size_t, int, bus_dmamap_t *);
                   1098: void   _bus_dmamap_destroy(bus_dma_tag_t, bus_dmamap_t);
                   1099: int    _bus_dmamap_load(bus_dma_tag_t, bus_dmamap_t, void *,
                   1100:            bus_size_t, struct proc *, int);
                   1101: int    _bus_dmamap_load_mbuf(bus_dma_tag_t, bus_dmamap_t,
                   1102:            struct mbuf *, int);
                   1103: int    _bus_dmamap_load_uio(bus_dma_tag_t, bus_dmamap_t,
                   1104:            struct uio *, int);
                   1105: int    _bus_dmamap_load_raw(bus_dma_tag_t, bus_dmamap_t,
                   1106:            bus_dma_segment_t *, int, bus_size_t, int);
                   1107: void   _bus_dmamap_unload(bus_dma_tag_t, bus_dmamap_t);
                   1108: void   _bus_dmamap_sync(bus_dma_tag_t, bus_dmamap_t, bus_addr_t,
                   1109:            bus_size_t, int);
                   1110:
                   1111: int    _bus_dmamem_alloc(bus_dma_tag_t tag, bus_size_t size,
                   1112:            bus_size_t alignment, bus_size_t boundary,
                   1113:            bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags);
                   1114: void   _bus_dmamem_free(bus_dma_tag_t tag, bus_dma_segment_t *segs,
                   1115:            int nsegs);
                   1116: int    _bus_dmamem_map(bus_dma_tag_t tag, bus_dma_segment_t *segs,
                   1117:            int nsegs, size_t size, caddr_t *kvap, int flags);
                   1118: void   _bus_dmamem_unmap(bus_dma_tag_t tag, caddr_t kva,
                   1119:            size_t size);
                   1120: paddr_t        _bus_dmamem_mmap(bus_dma_tag_t tag, bus_dma_segment_t *segs,
                   1121:            int nsegs, off_t off, int prot, int flags);
                   1122:
                   1123: int    _bus_dmamem_alloc_range(bus_dma_tag_t tag, bus_size_t size,
                   1124:            bus_size_t alignment, bus_size_t boundary,
                   1125:            bus_dma_segment_t *segs, int nsegs, int *rsegs, int flags,
                   1126:            paddr_t low, paddr_t high);
                   1127:
                   1128: /*
                   1129:  *      paddr_t bus_space_mmap(bus_space_tag_t t, bus_addr_t base,
                   1130:  *          off_t offset, int prot, int flags);
                   1131:  *
                   1132:  * Mmap an area of bus space.
                   1133:  */
                   1134:
                   1135: paddr_t x86_memio_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
                   1136:
                   1137:
                   1138: #endif /* _X86_BUS_DMA_PRIVATE */
                   1139:
                   1140: #endif /* _X86_BUS_H_ */

CVSweb