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

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

1.1       nbrk        1: /*     $OpenBSD: bus.h,v 1.6 2006/01/01 00:41:02 millert Exp $ */
                      2: /*
                      3:  * Copyright (c) 2003, Miodrag Vallat.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  *
                     14:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     15:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     16:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     17:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     18:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     19:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     20:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     21:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     22:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     23:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     24:  * POSSIBILITY OF SUCH DAMAGE.
                     25:  */
                     26:
                     27: /*
                     28:  * ``No-nonsense'' sparc bus_space implementation.
                     29:  *
                     30:  * This is a stripped down bus_space implementation for sparc, providing
                     31:  * simple enough functions, suitable for inlining.
                     32:  * To achieve this goal, it relies upon the following assumptions:
                     33:  * - everything is memory-mapped. Hence, tags are basically not used,
                     34:  *   and most operation are just simple pointer arithmetic with the handle.
                     35:  * - interrupt functions are not implemented; callers will provide their
                     36:  *   own wrappers on a need-to-do basis.
                     37:  */
                     38:
                     39: #ifndef        _SPARC_BUS_H_
                     40: #define        _SPARC_BUS_H_
                     41:
                     42: #include <machine/autoconf.h>
                     43:
                     44: #include <uvm/uvm_extern.h>
                     45:
                     46: #include <machine/pmap.h>
                     47:
                     48: typedef        u_int32_t       bus_space_handle_t;
                     49:
                     50: /*
                     51:  * bus_space_tag_t are pointer to *modified* rom_reg structures.
                     52:  * rr_iospace is used to also carry bus endianness information.
                     53:  */
                     54: typedef        struct rom_reg  *bus_space_tag_t;
                     55:
                     56: #define        TAG_LITTLE_ENDIAN               0x80000000
                     57:
                     58: #define        SET_TAG_BIG_ENDIAN(t)           ((t))->rr_iospace &= ~TAG_LITTLE_ENDIAN
                     59: #define        SET_TAG_LITTLE_ENDIAN(t)        ((t))->rr_iospace |= TAG_LITTLE_ENDIAN
                     60:
                     61: #define        IS_TAG_LITTLE_ENDIAN(t)         ((t)->rr_iospace & TAG_LITTLE_ENDIAN)
                     62:
                     63: typedef        u_int32_t       bus_addr_t;
                     64: typedef        u_int32_t       bus_size_t;
                     65:
                     66: /*
                     67:  * General bus_space function set
                     68:  */
                     69:
                     70: static int bus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
                     71:     bus_space_handle_t *);
                     72: static int bus_space_unmap(bus_space_tag_t, bus_space_handle_t,
                     73:     bus_size_t);
                     74:
                     75: #define        BUS_SPACE_BARRIER_READ  0
                     76: #define        BUS_SPACE_BARRIER_WRITE 1
                     77:
                     78: static void bus_space_barrier(bus_space_tag_t, bus_space_handle_t,
                     79:     bus_addr_t, bus_size_t, int);
                     80:
                     81: static void* bus_space_vaddr(bus_space_tag_t, bus_space_handle_t);
                     82: static int bus_space_subregion(bus_space_tag_t, bus_space_handle_t,
                     83:     bus_addr_t, bus_size_t, bus_space_handle_t *);
                     84:
                     85: static __inline__ int
                     86: bus_space_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size, int flags,
                     87:     bus_space_handle_t *handle)
                     88: {
                     89:        if ((*handle = (bus_space_handle_t)mapiodev(tag,
                     90:            addr, size)) != NULL)
                     91:                return (0);
                     92:
                     93:        return (ENOMEM);
                     94: }
                     95:
                     96: static __inline__ int
                     97: bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size)
                     98: {
                     99:        /*
                    100:         * The mapiodev() call eventually ended up as a set of pmap_kenter_pa()
                    101:         * calls. Although the iospace va will not be reclaimed, at least
                    102:         * relinquish the wiring.
                    103:         */
                    104:        pmap_kremove((vaddr_t)handle, size);
                    105:        pmap_update(pmap_kernel());
                    106:        return (0);
                    107: }
                    108:
                    109: static __inline__ void
                    110: bus_space_barrier(bus_space_tag_t tag, bus_space_handle_t handle,
                    111:     bus_addr_t offset, bus_size_t size, int flags)
                    112: {
                    113:        /* no membar is necessary for sparc so far */
                    114: }
                    115:
                    116: static __inline__ void *
                    117: bus_space_vaddr(bus_space_tag_t tag, bus_space_handle_t handle)
                    118: {
                    119:        u_int32_t iospace = tag->rr_iospace;
                    120:        void *rc;
                    121:
                    122:        tag->rr_iospace &= ~TAG_LITTLE_ENDIAN;
                    123:        rc = (void *)(REG2PHYS(tag, 0) | PMAP_NC);
                    124:        tag->rr_iospace = iospace;
                    125:        return (rc);
                    126: }
                    127:
                    128: static __inline__ int
                    129: bus_space_subregion(bus_space_tag_t tag, bus_space_handle_t handle,
                    130:     bus_addr_t offset, bus_size_t size, bus_space_handle_t *newh)
                    131: {
                    132:        *newh = handle + offset;
                    133:        return (0);
                    134: }
                    135:
                    136: /*
                    137:  * Read/Write/Region functions
                    138:  * Most of these are straightforward and assume that everything is properly
                    139:  * aligned.
                    140:  */
                    141:
                    142: #define        bus_space_read_1(tag, handle, offset) \
                    143:        ((void)(tag), *(volatile u_int8_t *)((handle) + (offset)))
                    144: #define        __bus_space_read_2(tag, handle, offset) \
                    145:        *(volatile u_int16_t *)((handle) + (offset))
                    146: #define        __bus_space_read_4(tag, handle, offset) \
                    147:        *(volatile u_int32_t *)((handle) + (offset))
                    148: #define        bus_space_read_2(tag, handle, offset) \
                    149:        ((IS_TAG_LITTLE_ENDIAN(tag)) ? \
                    150:                letoh16(__bus_space_read_2(tag, handle, offset)) : \
                    151:                __bus_space_read_2(tag, handle, offset))
                    152: #define        bus_space_read_4(tag, handle, offset) \
                    153:        ((IS_TAG_LITTLE_ENDIAN(tag)) ? \
                    154:                letoh32(__bus_space_read_4(tag, handle, offset)) : \
                    155:                __bus_space_read_4(tag, handle, offset))
                    156:
                    157: static void bus_space_read_multi_1(bus_space_tag_t, bus_space_handle_t,
                    158:     bus_addr_t, u_int8_t *, size_t);
                    159:
                    160: static __inline__ void
                    161: bus_space_read_multi_1(bus_space_tag_t tag, bus_space_handle_t handle,
                    162:     bus_addr_t offset, u_int8_t *dest, size_t count)
                    163: {
                    164:        while ((int)--count >= 0)
                    165:                *dest++ = bus_space_read_1(tag, handle, offset);
                    166: }
                    167:
                    168: static void bus_space_read_multi_2(bus_space_tag_t, bus_space_handle_t,
                    169:     bus_addr_t, u_int16_t *, size_t);
                    170:
                    171: static __inline__ void
                    172: bus_space_read_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
                    173:     bus_addr_t offset, u_int16_t *dest, size_t count)
                    174: {
                    175:        while ((int)--count >= 0)
                    176:                *dest++ = bus_space_read_2(tag, handle, offset);
                    177: }
                    178:
                    179: static void bus_space_read_multi_4(bus_space_tag_t, bus_space_handle_t,
                    180:     bus_addr_t, u_int32_t *, size_t);
                    181:
                    182: static __inline__ void
                    183: bus_space_read_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
                    184:     bus_addr_t offset, u_int32_t *dest, size_t count)
                    185: {
                    186:        while ((int)--count >= 0)
                    187:                *dest++ = bus_space_read_4(tag, handle, offset);
                    188: }
                    189:
                    190: static void bus_space_read_raw_multi_2(bus_space_tag_t, bus_space_handle_t,
                    191:     bus_addr_t, u_int8_t *, size_t);
                    192:
                    193: static __inline__ void
                    194: bus_space_read_raw_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
                    195:     bus_addr_t offset, u_int8_t *dest, size_t size)
                    196: {
                    197:        size >>= 1;
                    198:        while ((int)--size >= 0) {
                    199:                *(u_int16_t *)dest =
                    200:                    __bus_space_read_2(tag, handle, offset);
                    201:                dest += 2;
                    202:        }
                    203: }
                    204:
                    205: static void bus_space_read_raw_multi_4(bus_space_tag_t, bus_space_handle_t,
                    206:     bus_addr_t, u_int8_t *, size_t);
                    207:
                    208: static __inline__ void
                    209: bus_space_read_raw_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
                    210:     bus_addr_t offset, u_int8_t *dest, size_t size)
                    211: {
                    212:        size >>= 2;
                    213:        while ((int)--size >= 0) {
                    214:                *(u_int32_t *)dest =
                    215:                    __bus_space_read_4(tag, handle, offset);
                    216:                dest += 4;
                    217:        }
                    218: }
                    219:
                    220: #define        bus_space_write_1(tag, handle, offset, value) \
                    221:        ((void)(tag), *(volatile u_int8_t *)((handle) + (offset)) = (value))
                    222: #define        __bus_space_write_2(tag, handle, offset, value) \
                    223:        *(volatile u_int16_t *)((handle) + (offset)) = (value)
                    224: #define        __bus_space_write_4(tag, handle, offset, value) \
                    225:        *(volatile u_int32_t *)((handle) + (offset)) = (value)
                    226: #define        bus_space_write_2(tag, handle, offset, value) \
                    227:        __bus_space_write_2(tag, handle, offset, \
                    228:            (IS_TAG_LITTLE_ENDIAN(tag)) ? htole16(value) : (value))
                    229: #define        bus_space_write_4(tag, handle, offset, value) \
                    230:        __bus_space_write_4(tag, handle, offset, \
                    231:            (IS_TAG_LITTLE_ENDIAN(tag)) ? htole32(value) : (value))
                    232:
                    233: static void bus_space_write_multi_1(bus_space_tag_t, bus_space_handle_t,
                    234:     bus_addr_t, u_int8_t *, size_t);
                    235:
                    236: static __inline__ void
                    237: bus_space_write_multi_1(bus_space_tag_t tag, bus_space_handle_t handle,
                    238:     bus_addr_t offset, u_int8_t *dest, size_t count)
                    239: {
                    240:        while ((int)--count >= 0)
                    241:                bus_space_write_1(tag, handle, offset, *dest++);
                    242: }
                    243:
                    244: static void bus_space_write_multi_2(bus_space_tag_t, bus_space_handle_t,
                    245:     bus_addr_t, u_int16_t *, size_t);
                    246:
                    247: static __inline__ void
                    248: bus_space_write_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
                    249:     bus_addr_t offset, u_int16_t *dest, size_t count)
                    250: {
                    251:        while ((int)--count >= 0)
                    252:                bus_space_write_2(tag, handle, offset, *dest++);
                    253: }
                    254:
                    255: static void bus_space_write_multi_4(bus_space_tag_t, bus_space_handle_t,
                    256:     bus_addr_t, u_int32_t *, size_t);
                    257:
                    258: static __inline__ void
                    259: bus_space_write_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
                    260:     bus_addr_t offset, u_int32_t *dest, size_t count)
                    261: {
                    262:        while ((int)--count >= 0)
                    263:                bus_space_write_4(tag, handle, offset, *dest);
                    264: }
                    265:
                    266: static void bus_space_write_raw_multi_2(bus_space_tag_t, bus_space_handle_t,
                    267:     bus_addr_t, u_int8_t *, size_t);
                    268:
                    269: static __inline__ void
                    270: bus_space_write_raw_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
                    271:     bus_addr_t offset, u_int8_t *dest, size_t size)
                    272: {
                    273:        size >>= 1;
                    274:        while ((int)--size >= 0) {
                    275:                __bus_space_write_2(tag, handle, offset,
                    276:                    *(u_int16_t *)dest);
                    277:                dest += 2;
                    278:        }
                    279: }
                    280:
                    281: static void bus_space_write_raw_multi_4(bus_space_tag_t, bus_space_handle_t,
                    282:     bus_addr_t, u_int8_t *, size_t);
                    283:
                    284: static __inline__ void
                    285: bus_space_write_raw_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
                    286:     bus_addr_t offset, u_int8_t *dest, size_t size)
                    287: {
                    288:        size >>= 2;
                    289:        while ((int)--size >= 0) {
                    290:                __bus_space_write_4(tag, handle, offset,
                    291:                    *(u_int32_t *)dest);
                    292:                dest += 4;
                    293:        }
                    294: }
                    295:
                    296: static void bus_space_set_multi_1(bus_space_tag_t, bus_space_handle_t,
                    297:     bus_addr_t, u_int8_t, size_t);
                    298:
                    299: static __inline__ void
                    300: bus_space_set_multi_1(bus_space_tag_t tag, bus_space_handle_t handle,
                    301:     bus_addr_t offset, u_int8_t value, size_t count)
                    302: {
                    303:        while ((int)--count >= 0)
                    304:                bus_space_write_1(tag, handle, offset, value);
                    305: }
                    306:
                    307: static void bus_space_set_multi_2(bus_space_tag_t, bus_space_handle_t,
                    308:     bus_addr_t, u_int16_t, size_t);
                    309:
                    310: static __inline__ void
                    311: bus_space_set_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
                    312:     bus_addr_t offset, u_int16_t value, size_t count)
                    313: {
                    314:        while ((int)--count >= 0)
                    315:                bus_space_write_2(tag, handle, offset, value);
                    316: }
                    317:
                    318: static void bus_space_set_multi_4(bus_space_tag_t, bus_space_handle_t,
                    319:     bus_addr_t, u_int32_t, size_t);
                    320:
                    321: static __inline__ void
                    322: bus_space_set_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
                    323:     bus_addr_t offset, u_int32_t value, size_t count)
                    324: {
                    325:        while ((int)--count >= 0)
                    326:                bus_space_write_4(tag, handle, offset, value);
                    327: }
                    328:
                    329: static void bus_space_write_region_1(bus_space_tag_t, bus_space_handle_t,
                    330:     bus_addr_t, u_int8_t *, size_t);
                    331:
                    332: static __inline__ void
                    333: bus_space_write_region_1(bus_space_tag_t tag, bus_space_handle_t handle,
                    334:     bus_addr_t offset, u_int8_t *dest, size_t count)
                    335: {
                    336:        while ((int)--count >= 0)
                    337:                bus_space_write_1(tag, handle, offset++, *dest++);
                    338: }
                    339:
                    340: static void bus_space_write_region_2(bus_space_tag_t, bus_space_handle_t,
                    341:     bus_addr_t, u_int16_t *, size_t);
                    342:
                    343: static __inline__ void
                    344: bus_space_write_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
                    345:     bus_addr_t offset, u_int16_t *dest, size_t count)
                    346: {
                    347:        while ((int)--count >= 0) {
                    348:                bus_space_write_2(tag, handle, offset, *dest++);
                    349:                offset += 2;
                    350:        }
                    351: }
                    352:
                    353: static void bus_space_write_region_4(bus_space_tag_t, bus_space_handle_t,
                    354:     bus_addr_t, u_int32_t *, size_t);
                    355:
                    356: static __inline__ void
                    357: bus_space_write_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
                    358:     bus_addr_t offset, u_int32_t *dest, size_t count)
                    359: {
                    360:        while ((int)--count >= 0) {
                    361:                bus_space_write_4(tag, handle, offset, *dest++);
                    362:                offset +=4;
                    363:        }
                    364: }
                    365:
                    366: static void bus_space_write_raw_region_2(bus_space_tag_t, bus_space_handle_t,
                    367:     bus_addr_t, u_int8_t *, size_t);
                    368:
                    369: static __inline__ void
                    370: bus_space_write_raw_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
                    371:     bus_addr_t offset, u_int8_t *dest, size_t size)
                    372: {
                    373:        size >>= 1;
                    374:        while ((int)--size >= 0) {
                    375:                __bus_space_write_2(tag, handle, offset, *(u_int16_t *)dest);
                    376:                offset += 2;
                    377:                dest += 2;
                    378:        }
                    379: }
                    380:
                    381: static void bus_space_write_raw_region_4(bus_space_tag_t, bus_space_handle_t,
                    382:     bus_addr_t, u_int8_t *, size_t);
                    383:
                    384: static __inline__ void
                    385: bus_space_write_raw_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
                    386:     bus_addr_t offset, u_int8_t *dest, size_t size)
                    387: {
                    388:        size >>= 2;
                    389:        while ((int)--size >= 0) {
                    390:                __bus_space_write_4(tag, handle, offset, *(u_int32_t *)dest);
                    391:                offset += 4;
                    392:                dest += 4;
                    393:        }
                    394: }
                    395:
                    396: static void bus_space_read_region_1(bus_space_tag_t, bus_space_handle_t,
                    397:     bus_addr_t, u_int8_t *, size_t);
                    398:
                    399: static __inline__ void
                    400: bus_space_read_region_1(bus_space_tag_t tag, bus_space_handle_t handle,
                    401:     bus_addr_t offset, u_int8_t *dest, size_t count)
                    402: {
                    403:        while ((int)--count >= 0)
                    404:                *dest++ = bus_space_read_1(tag, handle, offset++);
                    405: }
                    406:
                    407: static void bus_space_read_region_2(bus_space_tag_t, bus_space_handle_t,
                    408:     bus_addr_t, u_int16_t *, size_t);
                    409:
                    410: static __inline__ void
                    411: bus_space_read_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
                    412:     bus_addr_t offset, u_int16_t *dest, size_t count)
                    413: {
                    414:        while ((int)--count >= 0) {
                    415:                *dest++ = bus_space_read_2(tag, handle, offset);
                    416:                offset += 2;
                    417:        }
                    418: }
                    419:
                    420: static void bus_space_read_region_4(bus_space_tag_t, bus_space_handle_t,
                    421:     bus_addr_t, u_int32_t *, size_t);
                    422:
                    423: static __inline__ void
                    424: bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
                    425:     bus_addr_t offset, u_int32_t *dest, size_t count)
                    426: {
                    427:        while ((int)--count >= 0) {
                    428:                *dest++ = bus_space_read_4(tag, handle, offset);
                    429:                offset += 4;
                    430:        }
                    431: }
                    432:
                    433: static void bus_space_set_region_1(bus_space_tag_t, bus_space_handle_t,
                    434:     bus_addr_t, u_int8_t, size_t);
                    435:
                    436: static __inline__ void
                    437: bus_space_set_region_1(bus_space_tag_t tag, bus_space_handle_t handle,
                    438:     bus_addr_t offset, u_int8_t value, size_t count)
                    439: {
                    440:        while ((int)--count >= 0)
                    441:                bus_space_write_1(tag, handle, offset++, value);
                    442: }
                    443:
                    444: static void bus_space_set_region_2(bus_space_tag_t, bus_space_handle_t,
                    445:     bus_addr_t, u_int16_t, size_t);
                    446:
                    447: static __inline__ void
                    448: bus_space_set_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
                    449:     bus_addr_t offset, u_int16_t value, size_t count)
                    450: {
                    451:        while ((int)--count >= 0) {
                    452:                bus_space_write_2(tag, handle, offset, value);
                    453:                offset += 2;
                    454:        }
                    455: }
                    456:
                    457: static void bus_space_set_region_4(bus_space_tag_t, bus_space_handle_t,
                    458:     bus_addr_t, u_int32_t, size_t);
                    459:
                    460: static __inline__ void
                    461: bus_space_set_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
                    462:     bus_addr_t offset, u_int32_t value, size_t count)
                    463: {
                    464:        while ((int)--count >= 0) {
                    465:                bus_space_write_4(tag, handle, offset, value);
                    466:                offset += 4;
                    467:        }
                    468: }
                    469:
                    470: static void bus_space_read_raw_region_2(bus_space_tag_t, bus_space_handle_t,
                    471:     bus_addr_t, u_int8_t *, size_t);
                    472:
                    473: static __inline__ void
                    474: bus_space_read_raw_region_2(bus_space_tag_t tag, bus_space_handle_t handle,
                    475:     bus_addr_t offset, u_int8_t *dest, size_t size)
                    476: {
                    477:        size >>= 1;
                    478:        while ((int)--size >= 0) {
                    479:                *(u_int16_t *)dest = __bus_space_read_2(tag, handle, offset);
                    480:                offset += 2;
                    481:                dest += 2;
                    482:        }
                    483: }
                    484:
                    485: static void bus_space_read_raw_region_4(bus_space_tag_t, bus_space_handle_t,
                    486:     bus_addr_t, u_int8_t *, size_t);
                    487:
                    488: static __inline__ void
                    489: bus_space_read_raw_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
                    490:     bus_addr_t offset, u_int8_t *dest, size_t size)
                    491: {
                    492:        size >>= 2;
                    493:        while ((int)--size >= 0) {
                    494:                *(u_int32_t *)dest = __bus_space_read_4(tag, handle, offset);
                    495:                offset += 4;
                    496:                dest += 4;
                    497:        }
                    498: }
                    499:
                    500: #endif /* _SPARC_BUS_H_ */

CVSweb