[BACK]Return to bus_space.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / powerpc / powerpc

Annotation of src/sys/arch/powerpc/powerpc/bus_space.c, Revision 1.2

1.2     ! matt        1: /*     $NetBSD: bus_space.c,v 1.1 2003/03/15 08:03:19 matt Exp $       */
1.1       matt        2:
                      3: /*-
                      4:  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                      9:  * NASA Ames Research Center.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the NetBSD
                     22:  *     Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/kernel.h>
                     43: #include <sys/device.h>
                     44: #include <sys/endian.h>
                     45: #include <sys/extent.h>
                     46: #include <sys/malloc.h>
                     47:
                     48: #include <uvm/uvm_extern.h>
                     49:
                     50: #define _POWERPC_BUS_SPACE_PRIVATE
                     51: #include <machine/bus.h>
                     52:
                     53: #ifdef PPC_OEA
                     54: #include <powerpc/oea/bat.h>
                     55: #include <powerpc/oea/pte.h>
                     56: #endif
                     57:
                     58: /* read_N */
                     59: u_int8_t bsr1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     60: u_int16_t bsr2(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     61: u_int32_t bsr4(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     62: u_int64_t bsr8(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     63:
                     64: /* write_N */
                     65: void bsw1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t);
                     66: void bsw2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
                     67: void bsw4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
                     68: void bsw8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
                     69:
                     70: static const struct powerpc_bus_space_scalar scalar_ops = {
                     71:        bsr1, bsr2, bsr4, bsr8,
                     72:        bsw1, bsw2, bsw4, bsw8
                     73: };
                     74:
                     75: /* read_N byte reverse */
                     76: u_int16_t bsr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     77: u_int32_t bsr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     78: u_int64_t bsr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     79:
                     80: /* write_N byte reverse */
                     81: void bsw2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
                     82: void bsw4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
                     83: void bsw8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
                     84:
                     85: static const struct powerpc_bus_space_scalar scalar_rb_ops = {
                     86:        bsr1, bsr2rb, bsr4rb, bsr8rb,
                     87:        bsw1, bsw2rb, bsw4rb, bsw8rb
                     88: };
                     89:
                     90: /* read_multi_N */
                     91: void bsrm1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
                     92:        size_t);
                     93: void bsrm2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                     94:        size_t);
                     95: void bsrm4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                     96:        size_t);
                     97: void bsrm8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                     98:        size_t);
                     99:
                    100: /* write_multi_N */
                    101: void bswm1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    102:        const u_int8_t *, size_t);
                    103: void bswm2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    104:        const u_int16_t *, size_t);
                    105: void bswm4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    106:        const u_int32_t *, size_t);
                    107: void bswm8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    108:        const u_int64_t *, size_t);
                    109:
                    110: static const struct powerpc_bus_space_group multi_ops = {
                    111:        bsrm1, bsrm2, bsrm4, bsrm8,
                    112:        bswm1, bswm2, bswm4, bswm8
                    113: };
                    114:
                    115: /* read_multi_N byte reversed */
                    116: void bsrm2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    117:        size_t);
                    118: void bsrm4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    119:        size_t);
                    120: void bsrm8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    121:        size_t);
                    122:
                    123: /* write_multi_N byte reversed */
                    124: void bswm2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    125:        const u_int16_t *, size_t);
                    126: void bswm4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    127:        const u_int32_t *, size_t);
                    128: void bswm8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    129:        const u_int64_t *, size_t);
                    130:
                    131: static const struct powerpc_bus_space_group multi_rb_ops = {
                    132:        bsrm1, bsrm2rb, bsrm4rb, bsrm8rb,
                    133:        bswm1, bswm2rb, bswm4rb, bswm8rb
                    134: };
                    135:
                    136: /* read_region_N */
                    137: void bsrr1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
                    138:        size_t);
                    139: void bsrr2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    140:        size_t);
                    141: void bsrr4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    142:        size_t);
                    143: void bsrr8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    144:        size_t);
                    145:
                    146: /* write_region_N */
                    147: void bswr1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    148:        const u_int8_t *, size_t);
                    149: void bswr2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    150:        const u_int16_t *, size_t);
                    151: void bswr4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    152:        const u_int32_t *, size_t);
                    153: void bswr8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    154:        const u_int64_t *, size_t);
                    155:
                    156: static const struct powerpc_bus_space_group region_ops = {
                    157:        bsrr1, bsrr2, bsrr4, bsrr8,
                    158:        bswr1, bswr2, bswr4, bswr8
                    159: };
                    160:
                    161: void bsrr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    162:        size_t);
                    163: void bsrr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    164:        size_t);
                    165: void bsrr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    166:        size_t);
                    167:
                    168: void bswr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    169:        const u_int16_t *, size_t);
                    170: void bswr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    171:        const u_int32_t *, size_t);
                    172: void bswr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    173:        const u_int64_t *, size_t);
                    174:
                    175: static const struct powerpc_bus_space_group region_rb_ops = {
                    176:        bsrr1, bsrr2rb, bsrr4rb, bsrr8rb,
                    177:        bswr1, bswr2rb, bswr4rb, bswr8rb
                    178: };
                    179:
                    180: /* set_region_n */
                    181: void bssr1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t,
                    182:        size_t);
                    183: void bssr2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
                    184:        size_t);
                    185: void bssr4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
                    186:        size_t);
                    187: void bssr8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
                    188:        size_t);
                    189:
                    190: static const struct powerpc_bus_space_set set_ops = {
                    191:        bssr1, bssr2, bssr4, bssr8,
                    192: };
                    193:
                    194: void bssr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
                    195:        size_t);
                    196: void bssr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
                    197:        size_t);
                    198: void bssr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
                    199:        size_t);
                    200:
                    201: static const struct powerpc_bus_space_set set_rb_ops = {
                    202:        bssr1, bssr2rb, bssr4rb, bssr8rb,
                    203: };
                    204:
                    205: /* copy_region_N */
                    206: void bscr1(bus_space_tag_t, bus_space_handle_t,
                    207:     bus_size_t, bus_space_handle_t, bus_size_t, size_t);
                    208: void bscr2(bus_space_tag_t, bus_space_handle_t,
                    209:     bus_size_t, bus_space_handle_t, bus_size_t, size_t);
                    210: void bscr4(bus_space_tag_t, bus_space_handle_t,
                    211:     bus_size_t, bus_space_handle_t, bus_size_t, size_t);
                    212: void bscr8(bus_space_tag_t, bus_space_handle_t,
                    213:     bus_size_t, bus_space_handle_t, bus_size_t, size_t);
                    214:
                    215: static const struct powerpc_bus_space_copy copy_ops = {
                    216:        bscr1, bscr2, bscr4, bscr8
                    217: };
                    218:
                    219: /*
                    220:  * Strided versions
                    221:  */
                    222: /* read_N */
                    223: u_int8_t bsr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    224: u_int16_t bsr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    225: u_int32_t bsr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    226: u_int64_t bsr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    227:
                    228: /* write_N */
                    229: void bsw1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t);
                    230: void bsw2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
                    231: void bsw4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
                    232: void bsw8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
                    233:
                    234: static const struct powerpc_bus_space_scalar scalar_strided_ops = {
                    235:        bsr1_s, bsr2_s, bsr4_s, bsr8_s,
                    236:        bsw1_s, bsw2_s, bsw4_s, bsw8_s
                    237: };
                    238:
                    239: /* read_N */
                    240: u_int16_t bsr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    241: u_int32_t bsr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    242: u_int64_t bsr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    243:
                    244: /* write_N */
                    245: void bsw2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
                    246: void bsw4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
                    247: void bsw8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
                    248:
                    249: static const struct powerpc_bus_space_scalar scalar_rb_strided_ops = {
                    250:        bsr1_s, bsr2rb_s, bsr4rb_s, bsr8rb_s,
                    251:        bsw1_s, bsw2rb_s, bsw4rb_s, bsw8rb_s
                    252: };
                    253:
                    254: /* read_multi_N */
                    255: void bsrm1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
                    256:        size_t);
                    257: void bsrm2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    258:        size_t);
                    259: void bsrm4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    260:        size_t);
                    261: void bsrm8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    262:        size_t);
                    263:
                    264: /* write_multi_N */
                    265: void bswm1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    266:        const u_int8_t *, size_t);
                    267: void bswm2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    268:        const u_int16_t *, size_t);
                    269: void bswm4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    270:        const u_int32_t *, size_t);
                    271: void bswm8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    272:        const u_int64_t *, size_t);
                    273:
                    274: static const struct powerpc_bus_space_group multi_strided_ops = {
                    275:        bsrm1_s, bsrm2_s, bsrm4_s, bsrm8_s,
                    276:        bswm1_s, bswm2_s, bswm4_s, bswm8_s
                    277: };
                    278:
                    279: /* read_multi_N */
                    280: void bsrm2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    281:        size_t);
                    282: void bsrm4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    283:        size_t);
                    284: void bsrm8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    285:        size_t);
                    286:
                    287: /* write_multi_N */
                    288: void bswm2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    289:        const u_int16_t *, size_t);
                    290: void bswm4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    291:        const u_int32_t *, size_t);
                    292: void bswm8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    293:        const u_int64_t *, size_t);
                    294:
                    295: static const struct powerpc_bus_space_group multi_rb_strided_ops = {
                    296:        bsrm1_s, bsrm2rb_s, bsrm4rb_s, bsrm8rb_s,
                    297:        bswm1_s, bswm2rb_s, bswm4rb_s, bswm8rb_s
                    298: };
                    299:
                    300: /* read_region_N */
                    301: void bsrr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
                    302:        size_t);
                    303: void bsrr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    304:        size_t);
                    305: void bsrr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    306:        size_t);
                    307: void bsrr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    308:        size_t);
                    309:
                    310: /* write_region_N */
                    311: void bswr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    312:        const u_int8_t *, size_t);
                    313: void bswr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    314:        const u_int16_t *, size_t);
                    315: void bswr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    316:        const u_int32_t *, size_t);
                    317: void bswr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    318:        const u_int64_t *, size_t);
                    319:
                    320: static const struct powerpc_bus_space_group region_strided_ops = {
                    321:        bsrr1_s, bsrr2_s, bsrr4_s, bsrr8_s,
                    322:        bswr1_s, bswr2_s, bswr4_s, bswr8_s
                    323: };
                    324:
                    325: /* read_region_N */
                    326: void bsrr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    327:        size_t);
                    328: void bsrr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    329:        size_t);
                    330: void bsrr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    331:        size_t);
                    332:
                    333: /* write_region_N */
                    334: void bswr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    335:        const u_int16_t *, size_t);
                    336: void bswr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    337:        const u_int32_t *, size_t);
                    338: void bswr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    339:        const u_int64_t *, size_t);
                    340:
                    341: static const struct powerpc_bus_space_group region_rb_strided_ops = {
                    342:        bsrr1_s, bsrr2rb_s, bsrr4rb_s, bsrr8rb_s,
                    343:        bswr1_s, bswr2rb_s, bswr4rb_s, bswr8rb_s
                    344: };
                    345:
                    346: /* set_region_N */
                    347: void bssr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t,
                    348:        size_t);
                    349: void bssr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
                    350:        size_t);
                    351: void bssr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
                    352:        size_t);
                    353: void bssr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
                    354:        size_t);
                    355:
                    356: static const struct powerpc_bus_space_set set_strided_ops = {
                    357:        bssr1_s, bssr2_s, bssr4_s, bssr8_s,
                    358: };
                    359:
                    360: /* set_region_N */
                    361: void bssr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
                    362:        size_t);
                    363: void bssr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
                    364:        size_t);
                    365: void bssr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
                    366:        size_t);
                    367:
                    368: static const struct powerpc_bus_space_set set_rb_strided_ops = {
                    369:        bssr1_s, bssr2rb_s, bssr4rb_s, bssr8rb_s,
                    370: };
                    371:
                    372: /* copy_region_N */
                    373: void bscr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    374:        bus_space_handle_t, bus_size_t, size_t);
                    375: void bscr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    376:        bus_space_handle_t, bus_size_t, size_t);
                    377: void bscr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    378:        bus_space_handle_t, bus_size_t, size_t);
                    379: void bscr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    380:        bus_space_handle_t, bus_size_t, size_t);
                    381:
                    382: static const struct powerpc_bus_space_copy copy_strided_ops = {
                    383:        bscr1_s, bscr2_s, bscr4_s, bscr8_s
                    384: };
                    385:
                    386: static paddr_t memio_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
                    387: static int memio_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
                    388:        bus_space_handle_t *);
                    389: static int memio_subregion(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    390:        bus_size_t, bus_space_handle_t *);
                    391: static void memio_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    392: static int memio_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t,
                    393:        bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
                    394: static void memio_free(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    395:
                    396: static int extent_flags;
                    397:
                    398: int
                    399: bus_space_init(struct powerpc_bus_space *t, const char *extent_name,
                    400:        caddr_t storage, size_t storage_size)
                    401: {
                    402:        if (t->pbs_extent == NULL) {
                    403:                t->pbs_extent = extent_create(extent_name, t->pbs_base,
                    404:                    t->pbs_limit-1, M_DEVBUF, storage, storage_size,
                    405:                    EX_NOCOALESCE|EX_NOWAIT);
                    406:                if (t->pbs_extent == NULL)
                    407:                        return ENOMEM;
                    408:        }
                    409:
                    410:        t->pbs_mmap = memio_mmap;
                    411:        t->pbs_map = memio_map;
                    412:        t->pbs_subregion = memio_subregion;
                    413:        t->pbs_unmap = memio_unmap;
                    414:        t->pbs_alloc = memio_alloc;
                    415:        t->pbs_free = memio_free;
                    416:
                    417:        if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
                    418:                t->pbs_scalar_stream = scalar_strided_ops;
                    419:                t->pbs_multi_stream = &multi_strided_ops;
                    420:                t->pbs_region_stream = &region_strided_ops;
                    421:                t->pbs_set_stream = &set_strided_ops;
                    422:                t->pbs_copy = &copy_strided_ops;
                    423:        } else {
                    424:                t->pbs_scalar_stream = scalar_ops;
                    425:                t->pbs_multi_stream = &multi_ops;
                    426:                t->pbs_region_stream = &region_ops;
                    427:                t->pbs_set_stream = &set_ops;
                    428:                t->pbs_copy = &copy_ops;
                    429:        }
                    430:
                    431: #if BYTE_ORDER == BIG_ENDIAN
                    432:        if (t->pbs_flags & _BUS_SPACE_BIG_ENDIAN) {
                    433:                if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
                    434:                        t->pbs_scalar = scalar_strided_ops;
                    435:                        t->pbs_multi = &multi_strided_ops;
                    436:                        t->pbs_region = &region_strided_ops;
                    437:                        t->pbs_set = &set_strided_ops;
                    438:                } else {
                    439:                        t->pbs_scalar = scalar_ops;
                    440:                        t->pbs_multi = &multi_ops;
                    441:                        t->pbs_region = &region_ops;
                    442:                        t->pbs_set = &set_ops;
                    443:                }
                    444:        } else {
                    445:                if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
                    446:                        t->pbs_scalar = scalar_rb_strided_ops;
                    447:                        t->pbs_multi = &multi_rb_strided_ops;
                    448:                        t->pbs_region = &region_rb_strided_ops;
                    449:                        t->pbs_set = &set_rb_strided_ops;
                    450:                } else {
                    451:                        t->pbs_scalar = scalar_rb_ops;
                    452:                        t->pbs_multi = &multi_rb_ops;
                    453:                        t->pbs_region = &region_rb_ops;
                    454:                        t->pbs_set = &set_rb_ops;
                    455:                }
                    456:        }
                    457: #else
                    458:        if (t->pbs_flags & _BUS_SPACE_LITTLE_ENDIAN) {
                    459:                if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
                    460:                        t->pbs_scalar = scalar_strided_ops;
                    461:                        t->pbs_multi = &multi_strided_ops;
                    462:                        t->pbs_region = &region_strided_ops;
                    463:                        t->pbs_set = &set_strided_ops;
                    464:                } else {
                    465:                        t->pbs_scalar = scalar_ops;
                    466:                        t->pbs_multi = &multi_ops;
                    467:                        t->pbs_region = &region_ops;
                    468:                        t->pbs_set = &set_ops;
                    469:                }
                    470:        } else {
                    471:                if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
                    472:                        t->pbs_scalar = scalar_rb_strided_ops;
                    473:                        t->pbs_multi = &multi_rb_strided_ops;
                    474:                        t->pbs_region = &region_rb_strided_ops;
                    475:                        t->pbs_set = &set_rb_strided_ops;
                    476:                } else {
                    477:                        t->pbs_scalar = scalar_rb_ops;
                    478:                        t->pbs_multi = &multi_rb_ops;
                    479:                        t->pbs_region = &region_rb_ops;
                    480:                        t->pbs_set = &set_rb_ops;
                    481:                }
                    482:        }
                    483: #endif
                    484:        return 0;
                    485: }
                    486:
                    487: void
                    488: bus_space_mallocok(void)
                    489: {
                    490:        extent_flags = EX_MALLOCOK;
                    491: }
                    492:
                    493: /* ARGSUSED */
                    494: paddr_t
                    495: memio_mmap(bus_space_tag_t t, bus_addr_t bpa, off_t offset, int prot, int flags)
                    496: {
                    497:        return (trunc_page(bpa + offset));
                    498: }
                    499:
                    500: int
                    501: memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
                    502:        bus_space_handle_t *bshp)
                    503: {
                    504:        int error;
                    505:        paddr_t pa;
                    506:
                    507:        size = _BUS_SPACE_STRIDE(t, size);
                    508:
1.2     ! matt      509:        if (bpa + size > t->pbs_limit) {
        !           510: #ifdef DEBUG
        !           511:                printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: EINVAL\n",
        !           512:                    t, t->pbs_base, t->pbs_limit, bpa, size);
        !           513: #endif
1.1       matt      514:                return (EINVAL);
1.2     ! matt      515:        }
1.1       matt      516:
                    517:        /*
                    518:         * Can't map I/O space as linear.
                    519:         */
                    520:        if ((flags & BUS_SPACE_MAP_LINEAR) &&
                    521:            (t->pbs_flags & _BUS_SPACE_IO_TYPE))
                    522:                return (EOPNOTSUPP);
                    523:
                    524:        /*
                    525:         * Before we go any further, let's make sure that this
                    526:         * region is available.
                    527:         */
                    528:        error = extent_alloc_region(t->pbs_extent, bpa, size,
                    529:            EX_NOWAIT | extent_flags);
1.2     ! matt      530:        if (error) {
        !           531: #ifdef DEBUG
        !           532:                printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: %d\n",
        !           533:                    t, t->pbs_base, t->pbs_limit, bpa, size, error);
        !           534: #endif
1.1       matt      535:                return (error);
1.2     ! matt      536:        }
1.1       matt      537:
                    538:        pa = t->pbs_offset + bpa;
                    539: #ifdef PPC_OEA
                    540:        {
                    541:                /*
                    542:                 * Let's try to BAT map this address if possible
                    543:                 */
                    544:                register_t batu = battable[pa >> ADDR_SR_SHFT].batu;
                    545:                if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, pa) &&
                    546:                    BAT_VA_MATCH_P(batu, pa + size - 1)) {
                    547:                        *bshp = pa;
                    548:                        return (0);
                    549:                }
                    550:        }
                    551: #endif
                    552:        if (extent_flags == 0) {
                    553:                extent_free(t->pbs_extent, bpa, size, EX_NOWAIT);
1.2     ! matt      554: #ifdef DEBUG
        !           555:                printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: ENOMEM\n",
        !           556:                    t, t->pbs_base, t->pbs_limit, bpa, size);
        !           557: #endif
1.1       matt      558:                return (ENOMEM);
                    559:        }
                    560:        /*
                    561:         * Map this into the kernel pmap.
                    562:         */
                    563:        *bshp = (bus_space_handle_t) mapiodev(pa, size);
                    564:        if (*bshp == 0) {
                    565:                extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags);
1.2     ! matt      566: #ifdef DEBUG
        !           567:                printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: ENOMEM\n",
        !           568:                    t, t->pbs_base, t->pbs_limit, bpa, size);
        !           569: #endif
1.1       matt      570:                return (ENOMEM);
                    571:        }
                    572:
                    573:        return (0);
                    574: }
                    575:
                    576: int
                    577: memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset,
                    578:        bus_size_t size, bus_space_handle_t *bshp)
                    579: {
                    580:        *bshp = bsh + _BUS_SPACE_STRIDE(t, offset);
                    581:        return (0);
                    582: }
                    583:
                    584: void
                    585: memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
                    586: {
                    587:        bus_addr_t bpa;
                    588:        vaddr_t va = bsh;
                    589:        paddr_t pa;
                    590:
                    591:        size = _BUS_SPACE_STRIDE(t, size);
                    592:
                    593: #ifdef PPC_OEA
                    594:        {
                    595:                register_t batu = battable[va >> ADDR_SR_SHFT].batu;
                    596:                if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, va) &&
                    597:                    BAT_VA_MATCH_P(batu, va + size - 1)) {
                    598:                        pa = va;
                    599:                } else {
                    600:                        pmap_extract(pmap_kernel(), va, &pa);
                    601:                }
                    602:        }
                    603: #else
                    604:        pmap_extract(pmap_kernel(), va, &pa);
                    605: #endif
                    606:        bpa = pa - t->pbs_offset;
                    607:
                    608:        if (extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags)) {
                    609:                printf("memio_unmap: %s 0x%lx, size 0x%lx\n",
                    610:                    (t->pbs_flags & _BUS_SPACE_IO_TYPE) ? "port" : "mem",
                    611:                    (unsigned long)bpa, (unsigned long)size);
                    612:                printf("memio_unmap: can't free region\n");
                    613:        }
                    614: }
                    615:
                    616: int
                    617: memio_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
                    618:        bus_size_t size, bus_size_t alignment, bus_size_t boundary,
                    619:        int flags, bus_addr_t *bpap, bus_space_handle_t *bshp)
                    620: {
                    621:        u_long bpa;
                    622:        paddr_t pa;
                    623:        int error;
                    624:
                    625:        size = _BUS_SPACE_STRIDE(t, size);
                    626:
                    627:        if (rstart + size > t->pbs_limit)
                    628:                return (EINVAL);
                    629:
                    630:        /*
                    631:         * Can't map I/O space as linear.
                    632:         */
                    633:        if ((flags & BUS_SPACE_MAP_LINEAR) &&
                    634:            (t->pbs_flags & _BUS_SPACE_IO_TYPE))
                    635:                return (EOPNOTSUPP);
                    636:
                    637:        if (rstart < t->pbs_extent->ex_start || rend > t->pbs_extent->ex_end)
                    638:                panic("memio_alloc: bad region start/end");
                    639:
                    640:        error = extent_alloc_subregion(t->pbs_extent, rstart, rend, size,
                    641:            alignment, boundary, EX_FAST | EX_NOWAIT | extent_flags, &bpa);
                    642:
                    643:        if (error)
                    644:                return (error);
                    645:
                    646:        *bpap = bpa;
                    647:        pa = t->pbs_offset + bpa;
                    648: #ifdef PPC_OEA
                    649:        {
                    650:                register_t batu = battable[pa >> ADDR_SR_SHFT].batu;
                    651:                if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, pa) &&
                    652:                    BAT_VA_MATCH_P(batu, pa + size - 1)) {
                    653:                        *bshp = pa;
                    654:                        return (0);
                    655:                }
                    656:        }
                    657: #endif
                    658:        *bshp = (bus_space_handle_t) mapiodev(pa, size);
                    659:        if (*bshp == 0) {
                    660:                extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags);
                    661:                return (ENOMEM);
                    662:        }
                    663:
                    664:        return (0);
                    665: }
                    666:
                    667: void
                    668: memio_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
                    669: {
                    670:        /* memio_unmap() does all that we need to do. */
                    671:        memio_unmap(t, bsh, size);
                    672: }

CVSweb <webmaster@jp.NetBSD.org>