[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.12.4.3

1.12.4.3! garbled     1: /*     $NetBSD: bus_space.c,v 1.12.4.2 2007/08/02 21:59:35 macallan 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:  */
1.3       lukem      39:
                     40: #include <sys/cdefs.h>
1.12.4.3! garbled    41: __KERNEL_RCSID(0, "$NetBSD: bus_space.c,v 1.12.4.2 2007/08/02 21:59:35 macallan Exp $");
1.1       matt       42:
                     43: #include <sys/param.h>
                     44: #include <sys/systm.h>
                     45: #include <sys/kernel.h>
                     46: #include <sys/device.h>
                     47: #include <sys/endian.h>
                     48: #include <sys/extent.h>
                     49: #include <sys/malloc.h>
                     50:
                     51: #include <uvm/uvm_extern.h>
                     52:
                     53: #define _POWERPC_BUS_SPACE_PRIVATE
                     54: #include <machine/bus.h>
                     55:
1.7       sanjayl    56: #if defined (PPC_OEA) || defined (PPC_OEA64) || defined (PPC_OEA64_BRIDGE)
1.1       matt       57: #include <powerpc/oea/bat.h>
                     58: #include <powerpc/oea/pte.h>
1.5       kleink     59: #include <powerpc/oea/sr_601.h>
                     60: #include <powerpc/spr.h>
1.1       matt       61: #endif
                     62:
                     63: /* read_N */
                     64: u_int8_t bsr1(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     65: u_int16_t bsr2(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     66: u_int32_t bsr4(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     67: u_int64_t bsr8(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     68:
                     69: /* write_N */
                     70: void bsw1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t);
                     71: void bsw2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
                     72: void bsw4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
                     73: void bsw8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
                     74:
                     75: static const struct powerpc_bus_space_scalar scalar_ops = {
                     76:        bsr1, bsr2, bsr4, bsr8,
                     77:        bsw1, bsw2, bsw4, bsw8
                     78: };
                     79:
                     80: /* read_N byte reverse */
                     81: u_int16_t bsr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     82: u_int32_t bsr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     83: u_int64_t bsr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                     84:
                     85: /* write_N byte reverse */
                     86: void bsw2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
                     87: void bsw4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
                     88: void bsw8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
                     89:
                     90: static const struct powerpc_bus_space_scalar scalar_rb_ops = {
                     91:        bsr1, bsr2rb, bsr4rb, bsr8rb,
                     92:        bsw1, bsw2rb, bsw4rb, bsw8rb
                     93: };
                     94:
                     95: /* read_multi_N */
                     96: void bsrm1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
                     97:        size_t);
                     98: void bsrm2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                     99:        size_t);
                    100: void bsrm4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    101:        size_t);
                    102: void bsrm8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    103:        size_t);
                    104:
                    105: /* write_multi_N */
                    106: void bswm1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    107:        const u_int8_t *, size_t);
                    108: void bswm2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    109:        const u_int16_t *, size_t);
                    110: void bswm4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    111:        const u_int32_t *, size_t);
                    112: void bswm8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    113:        const u_int64_t *, size_t);
                    114:
                    115: static const struct powerpc_bus_space_group multi_ops = {
                    116:        bsrm1, bsrm2, bsrm4, bsrm8,
                    117:        bswm1, bswm2, bswm4, bswm8
                    118: };
                    119:
                    120: /* read_multi_N byte reversed */
                    121: void bsrm2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    122:        size_t);
                    123: void bsrm4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    124:        size_t);
                    125: void bsrm8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    126:        size_t);
                    127:
                    128: /* write_multi_N byte reversed */
                    129: void bswm2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    130:        const u_int16_t *, size_t);
                    131: void bswm4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    132:        const u_int32_t *, size_t);
                    133: void bswm8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    134:        const u_int64_t *, size_t);
                    135:
                    136: static const struct powerpc_bus_space_group multi_rb_ops = {
                    137:        bsrm1, bsrm2rb, bsrm4rb, bsrm8rb,
                    138:        bswm1, bswm2rb, bswm4rb, bswm8rb
                    139: };
                    140:
                    141: /* read_region_N */
                    142: void bsrr1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
                    143:        size_t);
                    144: void bsrr2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    145:        size_t);
                    146: void bsrr4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    147:        size_t);
                    148: void bsrr8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    149:        size_t);
                    150:
                    151: /* write_region_N */
                    152: void bswr1(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    153:        const u_int8_t *, size_t);
                    154: void bswr2(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    155:        const u_int16_t *, size_t);
                    156: void bswr4(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    157:        const u_int32_t *, size_t);
                    158: void bswr8(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    159:        const u_int64_t *, size_t);
                    160:
                    161: static const struct powerpc_bus_space_group region_ops = {
                    162:        bsrr1, bsrr2, bsrr4, bsrr8,
                    163:        bswr1, bswr2, bswr4, bswr8
                    164: };
                    165:
                    166: void bsrr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    167:        size_t);
                    168: void bsrr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    169:        size_t);
                    170: void bsrr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    171:        size_t);
                    172:
                    173: void bswr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    174:        const u_int16_t *, size_t);
                    175: void bswr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    176:        const u_int32_t *, size_t);
                    177: void bswr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    178:        const u_int64_t *, size_t);
                    179:
                    180: static const struct powerpc_bus_space_group region_rb_ops = {
                    181:        bsrr1, bsrr2rb, bsrr4rb, bsrr8rb,
                    182:        bswr1, bswr2rb, bswr4rb, bswr8rb
                    183: };
                    184:
                    185: /* set_region_n */
                    186: void bssr1(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t,
                    187:        size_t);
                    188: void bssr2(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
                    189:        size_t);
                    190: void bssr4(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
                    191:        size_t);
                    192: void bssr8(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
                    193:        size_t);
                    194:
                    195: static const struct powerpc_bus_space_set set_ops = {
                    196:        bssr1, bssr2, bssr4, bssr8,
                    197: };
                    198:
                    199: void bssr2rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
                    200:        size_t);
                    201: void bssr4rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
                    202:        size_t);
                    203: void bssr8rb(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
                    204:        size_t);
                    205:
                    206: static const struct powerpc_bus_space_set set_rb_ops = {
                    207:        bssr1, bssr2rb, bssr4rb, bssr8rb,
                    208: };
                    209:
                    210: /* copy_region_N */
                    211: void bscr1(bus_space_tag_t, bus_space_handle_t,
                    212:     bus_size_t, bus_space_handle_t, bus_size_t, size_t);
                    213: void bscr2(bus_space_tag_t, bus_space_handle_t,
                    214:     bus_size_t, bus_space_handle_t, bus_size_t, size_t);
                    215: void bscr4(bus_space_tag_t, bus_space_handle_t,
                    216:     bus_size_t, bus_space_handle_t, bus_size_t, size_t);
                    217: void bscr8(bus_space_tag_t, bus_space_handle_t,
                    218:     bus_size_t, bus_space_handle_t, bus_size_t, size_t);
                    219:
                    220: static const struct powerpc_bus_space_copy copy_ops = {
                    221:        bscr1, bscr2, bscr4, bscr8
                    222: };
                    223:
                    224: /*
                    225:  * Strided versions
                    226:  */
                    227: /* read_N */
                    228: u_int8_t bsr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    229: u_int16_t bsr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    230: u_int32_t bsr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    231: u_int64_t bsr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    232:
                    233: /* write_N */
                    234: void bsw1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t);
                    235: void bsw2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
                    236: void bsw4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
                    237: void bsw8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
                    238:
                    239: static const struct powerpc_bus_space_scalar scalar_strided_ops = {
                    240:        bsr1_s, bsr2_s, bsr4_s, bsr8_s,
                    241:        bsw1_s, bsw2_s, bsw4_s, bsw8_s
                    242: };
                    243:
                    244: /* read_N */
                    245: u_int16_t bsr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    246: u_int32_t bsr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    247: u_int64_t bsr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    248:
                    249: /* write_N */
                    250: void bsw2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t);
                    251: void bsw4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t);
                    252: void bsw8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t);
                    253:
                    254: static const struct powerpc_bus_space_scalar scalar_rb_strided_ops = {
                    255:        bsr1_s, bsr2rb_s, bsr4rb_s, bsr8rb_s,
                    256:        bsw1_s, bsw2rb_s, bsw4rb_s, bsw8rb_s
                    257: };
                    258:
                    259: /* read_multi_N */
                    260: void bsrm1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
                    261:        size_t);
                    262: void bsrm2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    263:        size_t);
                    264: void bsrm4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    265:        size_t);
                    266: void bsrm8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    267:        size_t);
                    268:
                    269: /* write_multi_N */
                    270: void bswm1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    271:        const u_int8_t *, size_t);
                    272: void bswm2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    273:        const u_int16_t *, size_t);
                    274: void bswm4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    275:        const u_int32_t *, size_t);
                    276: void bswm8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    277:        const u_int64_t *, size_t);
                    278:
                    279: static const struct powerpc_bus_space_group multi_strided_ops = {
                    280:        bsrm1_s, bsrm2_s, bsrm4_s, bsrm8_s,
                    281:        bswm1_s, bswm2_s, bswm4_s, bswm8_s
                    282: };
                    283:
                    284: /* read_multi_N */
                    285: void bsrm2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    286:        size_t);
                    287: void bsrm4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    288:        size_t);
                    289: void bsrm8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    290:        size_t);
                    291:
                    292: /* write_multi_N */
                    293: void bswm2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    294:        const u_int16_t *, size_t);
                    295: void bswm4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    296:        const u_int32_t *, size_t);
                    297: void bswm8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    298:        const u_int64_t *, size_t);
                    299:
                    300: static const struct powerpc_bus_space_group multi_rb_strided_ops = {
                    301:        bsrm1_s, bsrm2rb_s, bsrm4rb_s, bsrm8rb_s,
                    302:        bswm1_s, bswm2rb_s, bswm4rb_s, bswm8rb_s
                    303: };
                    304:
                    305: /* read_region_N */
                    306: void bsrr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t *,
                    307:        size_t);
                    308: void bsrr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    309:        size_t);
                    310: void bsrr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    311:        size_t);
                    312: void bsrr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    313:        size_t);
                    314:
                    315: /* write_region_N */
                    316: void bswr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    317:        const u_int8_t *, size_t);
                    318: void bswr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    319:        const u_int16_t *, size_t);
                    320: void bswr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    321:        const u_int32_t *, size_t);
                    322: void bswr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    323:        const u_int64_t *, size_t);
                    324:
                    325: static const struct powerpc_bus_space_group region_strided_ops = {
                    326:        bsrr1_s, bsrr2_s, bsrr4_s, bsrr8_s,
                    327:        bswr1_s, bswr2_s, bswr4_s, bswr8_s
                    328: };
                    329:
                    330: /* read_region_N */
                    331: void bsrr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t *,
                    332:        size_t);
                    333: void bsrr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t *,
                    334:        size_t);
                    335: void bsrr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t *,
                    336:        size_t);
                    337:
                    338: /* write_region_N */
                    339: void bswr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    340:        const u_int16_t *, size_t);
                    341: void bswr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    342:        const u_int32_t *, size_t);
                    343: void bswr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    344:        const u_int64_t *, size_t);
                    345:
                    346: static const struct powerpc_bus_space_group region_rb_strided_ops = {
                    347:        bsrr1_s, bsrr2rb_s, bsrr4rb_s, bsrr8rb_s,
                    348:        bswr1_s, bswr2rb_s, bswr4rb_s, bswr8rb_s
                    349: };
                    350:
                    351: /* set_region_N */
                    352: void bssr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int8_t,
                    353:        size_t);
                    354: void bssr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
                    355:        size_t);
                    356: void bssr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
                    357:        size_t);
                    358: void bssr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
                    359:        size_t);
                    360:
                    361: static const struct powerpc_bus_space_set set_strided_ops = {
                    362:        bssr1_s, bssr2_s, bssr4_s, bssr8_s,
                    363: };
                    364:
                    365: /* set_region_N */
                    366: void bssr2rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int16_t,
                    367:        size_t);
                    368: void bssr4rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int32_t,
                    369:        size_t);
                    370: void bssr8rb_s(bus_space_tag_t, bus_space_handle_t, bus_size_t, u_int64_t,
                    371:        size_t);
                    372:
                    373: static const struct powerpc_bus_space_set set_rb_strided_ops = {
                    374:        bssr1_s, bssr2rb_s, bssr4rb_s, bssr8rb_s,
                    375: };
                    376:
                    377: /* copy_region_N */
                    378: void bscr1_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    379:        bus_space_handle_t, bus_size_t, size_t);
                    380: void bscr2_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    381:        bus_space_handle_t, bus_size_t, size_t);
                    382: void bscr4_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    383:        bus_space_handle_t, bus_size_t, size_t);
                    384: void bscr8_s(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    385:        bus_space_handle_t, bus_size_t, size_t);
                    386:
                    387: static const struct powerpc_bus_space_copy copy_strided_ops = {
                    388:        bscr1_s, bscr2_s, bscr4_s, bscr8_s
                    389: };
                    390:
                    391: static paddr_t memio_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int);
                    392: static int memio_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
                    393:        bus_space_handle_t *);
                    394: static int memio_subregion(bus_space_tag_t, bus_space_handle_t, bus_size_t,
                    395:        bus_size_t, bus_space_handle_t *);
                    396: static void memio_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    397: static int memio_alloc(bus_space_tag_t, bus_addr_t, bus_addr_t, bus_size_t,
                    398:        bus_size_t, bus_size_t, int, bus_addr_t *, bus_space_handle_t *);
                    399: static void memio_free(bus_space_tag_t, bus_space_handle_t, bus_size_t);
                    400:
                    401: static int extent_flags;
                    402:
                    403: int
                    404: bus_space_init(struct powerpc_bus_space *t, const char *extent_name,
1.10      christos  405:        void *storage, size_t storage_size)
1.1       matt      406: {
                    407:        if (t->pbs_extent == NULL) {
                    408:                t->pbs_extent = extent_create(extent_name, t->pbs_base,
                    409:                    t->pbs_limit-1, M_DEVBUF, storage, storage_size,
                    410:                    EX_NOCOALESCE|EX_NOWAIT);
                    411:                if (t->pbs_extent == NULL)
                    412:                        return ENOMEM;
                    413:        }
                    414:
                    415:        t->pbs_mmap = memio_mmap;
                    416:        t->pbs_map = memio_map;
                    417:        t->pbs_subregion = memio_subregion;
                    418:        t->pbs_unmap = memio_unmap;
                    419:        t->pbs_alloc = memio_alloc;
                    420:        t->pbs_free = memio_free;
                    421:
                    422:        if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
                    423:                t->pbs_scalar_stream = scalar_strided_ops;
                    424:                t->pbs_multi_stream = &multi_strided_ops;
                    425:                t->pbs_region_stream = &region_strided_ops;
                    426:                t->pbs_set_stream = &set_strided_ops;
                    427:                t->pbs_copy = &copy_strided_ops;
                    428:        } else {
                    429:                t->pbs_scalar_stream = scalar_ops;
                    430:                t->pbs_multi_stream = &multi_ops;
                    431:                t->pbs_region_stream = &region_ops;
                    432:                t->pbs_set_stream = &set_ops;
                    433:                t->pbs_copy = &copy_ops;
                    434:        }
                    435:
                    436: #if BYTE_ORDER == BIG_ENDIAN
                    437:        if (t->pbs_flags & _BUS_SPACE_BIG_ENDIAN) {
                    438:                if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
                    439:                        t->pbs_scalar = scalar_strided_ops;
                    440:                        t->pbs_multi = &multi_strided_ops;
                    441:                        t->pbs_region = &region_strided_ops;
                    442:                        t->pbs_set = &set_strided_ops;
                    443:                } else {
                    444:                        t->pbs_scalar = scalar_ops;
                    445:                        t->pbs_multi = &multi_ops;
                    446:                        t->pbs_region = &region_ops;
                    447:                        t->pbs_set = &set_ops;
                    448:                }
                    449:        } else {
                    450:                if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
                    451:                        t->pbs_scalar = scalar_rb_strided_ops;
                    452:                        t->pbs_multi = &multi_rb_strided_ops;
                    453:                        t->pbs_region = &region_rb_strided_ops;
                    454:                        t->pbs_set = &set_rb_strided_ops;
                    455:                } else {
                    456:                        t->pbs_scalar = scalar_rb_ops;
                    457:                        t->pbs_multi = &multi_rb_ops;
                    458:                        t->pbs_region = &region_rb_ops;
                    459:                        t->pbs_set = &set_rb_ops;
                    460:                }
                    461:        }
                    462: #else
                    463:        if (t->pbs_flags & _BUS_SPACE_LITTLE_ENDIAN) {
                    464:                if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
                    465:                        t->pbs_scalar = scalar_strided_ops;
                    466:                        t->pbs_multi = &multi_strided_ops;
                    467:                        t->pbs_region = &region_strided_ops;
                    468:                        t->pbs_set = &set_strided_ops;
                    469:                } else {
                    470:                        t->pbs_scalar = scalar_ops;
                    471:                        t->pbs_multi = &multi_ops;
                    472:                        t->pbs_region = &region_ops;
                    473:                        t->pbs_set = &set_ops;
                    474:                }
                    475:        } else {
                    476:                if (t->pbs_flags & _BUS_SPACE_STRIDE_MASK) {
                    477:                        t->pbs_scalar = scalar_rb_strided_ops;
                    478:                        t->pbs_multi = &multi_rb_strided_ops;
                    479:                        t->pbs_region = &region_rb_strided_ops;
                    480:                        t->pbs_set = &set_rb_strided_ops;
                    481:                } else {
                    482:                        t->pbs_scalar = scalar_rb_ops;
                    483:                        t->pbs_multi = &multi_rb_ops;
                    484:                        t->pbs_region = &region_rb_ops;
                    485:                        t->pbs_set = &set_rb_ops;
                    486:                }
                    487:        }
                    488: #endif
                    489:        return 0;
                    490: }
                    491:
                    492: void
                    493: bus_space_mallocok(void)
                    494: {
                    495:        extent_flags = EX_MALLOCOK;
                    496: }
                    497:
                    498: /* ARGSUSED */
                    499: paddr_t
                    500: memio_mmap(bus_space_tag_t t, bus_addr_t bpa, off_t offset, int prot, int flags)
                    501: {
1.12.4.2  macallan  502:        paddr_t ret;
1.12.4.1  macallan  503:        /* XXX what about stride? */
1.12.4.2  macallan  504:        ret = trunc_page(t->pbs_offset + bpa + offset);
                    505: #ifdef DEBUG
                    506:        if (ret == 0) {
                    507:                printf("%s: [%08x, %08x %08x] mmaps to 0?!\n", __func__,
                    508:                    (uint32_t)t->pbs_offset, (uint32_t)bpa, (uint32_t)offset);
                    509:                return -1;
                    510:        }
                    511: #endif
                    512:        return ret;
1.1       matt      513: }
                    514:
                    515: int
                    516: memio_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size, int flags,
                    517:        bus_space_handle_t *bshp)
                    518: {
                    519:        int error;
                    520:        paddr_t pa;
                    521:
                    522:        size = _BUS_SPACE_STRIDE(t, size);
1.12.4.1  macallan  523:        bpa = _BUS_SPACE_STRIDE(t, bpa);
1.1       matt      524:
1.2       matt      525:        if (bpa + size > t->pbs_limit) {
                    526: #ifdef DEBUG
                    527:                printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: EINVAL\n",
                    528:                    t, t->pbs_base, t->pbs_limit, bpa, size);
1.12.4.2  macallan  529:
1.2       matt      530: #endif
1.1       matt      531:                return (EINVAL);
1.2       matt      532:        }
1.1       matt      533:
                    534:        /*
                    535:         * Can't map I/O space as linear.
                    536:         */
                    537:        if ((flags & BUS_SPACE_MAP_LINEAR) &&
1.12.4.2  macallan  538:            (t->pbs_flags & _BUS_SPACE_IO_TYPE)) {
1.1       matt      539:                return (EOPNOTSUPP);
1.12.4.2  macallan  540:        }
1.1       matt      541:
1.4       scw       542: #ifdef PPC_IBM4XX
                    543:        /*
                    544:         * XXX: Temporary kludge.
                    545:         * Don't bother checking the extent during very early bootstrap.
                    546:         */
                    547:        if (extent_flags) {
                    548: #endif
1.1       matt      549:        /*
                    550:         * Before we go any further, let's make sure that this
                    551:         * region is available.
                    552:         */
                    553:        error = extent_alloc_region(t->pbs_extent, bpa, size,
                    554:            EX_NOWAIT | extent_flags);
1.2       matt      555:        if (error) {
                    556: #ifdef DEBUG
                    557:                printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: %d\n",
                    558:                    t, t->pbs_base, t->pbs_limit, bpa, size, error);
                    559: #endif
1.1       matt      560:                return (error);
1.2       matt      561:        }
1.4       scw       562: #ifdef PPC_IBM4XX
                    563:        }
                    564: #endif
1.1       matt      565:
                    566:        pa = t->pbs_offset + bpa;
                    567: #ifdef PPC_OEA
1.5       kleink    568:        if ((mfpvr() >> 16) != MPC601) {
1.1       matt      569:                /*
                    570:                 * Let's try to BAT map this address if possible
                    571:                 */
                    572:                register_t batu = battable[pa >> ADDR_SR_SHFT].batu;
                    573:                if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, pa) &&
                    574:                    BAT_VA_MATCH_P(batu, pa + size - 1)) {
                    575:                        *bshp = pa;
                    576:                        return (0);
                    577:                }
1.5       kleink    578:        } else {
                    579:                /*
                    580:                 * Same as above, but via the MPC601's I/O segments
                    581:                 */
                    582:                register_t sr = iosrtable[pa >> ADDR_SR_SHFT];
1.11      garbled   583:                if (SR601_VALID_P(sr) && ((pa >> ADDR_SR_SHFT) ==
                    584:                    ((pa + size - 1) >> ADDR_SR_SHFT))) {
1.5       kleink    585:                        *bshp = pa;
                    586:                        return (0);
                    587:                }
1.1       matt      588:        }
                    589: #endif
1.4       scw       590: #ifndef PPC_IBM4XX
1.1       matt      591:        if (extent_flags == 0) {
                    592:                extent_free(t->pbs_extent, bpa, size, EX_NOWAIT);
1.2       matt      593: #ifdef DEBUG
                    594:                printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: ENOMEM\n",
                    595:                    t, t->pbs_base, t->pbs_limit, bpa, size);
                    596: #endif
1.1       matt      597:                return (ENOMEM);
                    598:        }
1.4       scw       599: #endif
1.1       matt      600:        /*
                    601:         * Map this into the kernel pmap.
                    602:         */
                    603:        *bshp = (bus_space_handle_t) mapiodev(pa, size);
                    604:        if (*bshp == 0) {
                    605:                extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags);
1.2       matt      606: #ifdef DEBUG
                    607:                printf("bus_space_map(%p[%x:%x], %#x, %#x) failed: ENOMEM\n",
                    608:                    t, t->pbs_base, t->pbs_limit, bpa, size);
                    609: #endif
1.1       matt      610:                return (ENOMEM);
                    611:        }
                    612:
                    613:        return (0);
                    614: }
                    615:
                    616: int
                    617: memio_subregion(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t offset,
                    618:        bus_size_t size, bus_space_handle_t *bshp)
                    619: {
                    620:        *bshp = bsh + _BUS_SPACE_STRIDE(t, offset);
                    621:        return (0);
                    622: }
                    623:
                    624: void
                    625: memio_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
                    626: {
                    627:        bus_addr_t bpa;
                    628:        vaddr_t va = bsh;
                    629:        paddr_t pa;
                    630:
                    631:        size = _BUS_SPACE_STRIDE(t, size);
                    632:
1.7       sanjayl   633: #if defined (PPC_OEA) && !defined (PPC_OEA64) && !defined (PPC_OEA64_BRIDGE)
1.5       kleink    634:        if ((mfpvr() >> 16) != MPC601) {
1.1       matt      635:                register_t batu = battable[va >> ADDR_SR_SHFT].batu;
                    636:                if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, va) &&
                    637:                    BAT_VA_MATCH_P(batu, va + size - 1)) {
                    638:                        pa = va;
1.8       matt      639:                        va = 0;
1.1       matt      640:                } else {
                    641:                        pmap_extract(pmap_kernel(), va, &pa);
                    642:                }
1.5       kleink    643:        } else {
                    644:                register_t sr = iosrtable[va >> ADDR_SR_SHFT];
1.12      garbled   645:                if (SR601_VALID_P(sr) && ((pa >> ADDR_SR_SHFT) ==
                    646:                    ((pa + size - 1) >> ADDR_SR_SHFT))) {
1.5       kleink    647:                        pa = va;
1.8       matt      648:                        va = 0;
1.5       kleink    649:                } else {
                    650:                        pmap_extract(pmap_kernel(), va, &pa);
                    651:                }
1.1       matt      652:        }
                    653: #else
                    654:        pmap_extract(pmap_kernel(), va, &pa);
                    655: #endif
                    656:        bpa = pa - t->pbs_offset;
                    657:
                    658:        if (extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags)) {
                    659:                printf("memio_unmap: %s 0x%lx, size 0x%lx\n",
                    660:                    (t->pbs_flags & _BUS_SPACE_IO_TYPE) ? "port" : "mem",
                    661:                    (unsigned long)bpa, (unsigned long)size);
                    662:                printf("memio_unmap: can't free region\n");
                    663:        }
1.8       matt      664:
1.9       freza     665:        unmapiodev(va, size);
1.1       matt      666: }
                    667:
                    668: int
                    669: memio_alloc(bus_space_tag_t t, bus_addr_t rstart, bus_addr_t rend,
                    670:        bus_size_t size, bus_size_t alignment, bus_size_t boundary,
                    671:        int flags, bus_addr_t *bpap, bus_space_handle_t *bshp)
                    672: {
                    673:        u_long bpa;
                    674:        paddr_t pa;
                    675:        int error;
                    676:
                    677:        size = _BUS_SPACE_STRIDE(t, size);
1.12.4.1  macallan  678:        rstart = _BUS_SPACE_STRIDE(t, rstart);
1.1       matt      679:
                    680:        if (rstart + size > t->pbs_limit)
                    681:                return (EINVAL);
                    682:
                    683:        /*
                    684:         * Can't map I/O space as linear.
                    685:         */
                    686:        if ((flags & BUS_SPACE_MAP_LINEAR) &&
                    687:            (t->pbs_flags & _BUS_SPACE_IO_TYPE))
                    688:                return (EOPNOTSUPP);
                    689:
                    690:        if (rstart < t->pbs_extent->ex_start || rend > t->pbs_extent->ex_end)
                    691:                panic("memio_alloc: bad region start/end");
                    692:
                    693:        error = extent_alloc_subregion(t->pbs_extent, rstart, rend, size,
                    694:            alignment, boundary, EX_FAST | EX_NOWAIT | extent_flags, &bpa);
                    695:
                    696:        if (error)
                    697:                return (error);
                    698:
                    699:        *bpap = bpa;
                    700:        pa = t->pbs_offset + bpa;
1.7       sanjayl   701: #if defined (PPC_OEA) && !defined (PPC_OEA64) && !defined (PPC_OEA64_BRIDGE)
1.5       kleink    702:        if ((mfpvr() >> 16) != MPC601) {
1.1       matt      703:                register_t batu = battable[pa >> ADDR_SR_SHFT].batu;
                    704:                if (BAT_VALID_P(batu, 0) && BAT_VA_MATCH_P(batu, pa) &&
                    705:                    BAT_VA_MATCH_P(batu, pa + size - 1)) {
                    706:                        *bshp = pa;
                    707:                        return (0);
                    708:                }
1.5       kleink    709:        } else {
                    710:                register_t sr = iosrtable[pa >> ADDR_SR_SHFT];
                    711:                if (SR601_VALID_P(sr) && SR601_PA_MATCH_P(sr, pa) &&
                    712:                    SR601_PA_MATCH_P(sr, pa + size - 1)) {
                    713:                        *bshp = pa;
                    714:                        return (0);
                    715:                }
1.1       matt      716:        }
                    717: #endif
                    718:        *bshp = (bus_space_handle_t) mapiodev(pa, size);
                    719:        if (*bshp == 0) {
                    720:                extent_free(t->pbs_extent, bpa, size, EX_NOWAIT | extent_flags);
                    721:                return (ENOMEM);
                    722:        }
                    723:
                    724:        return (0);
                    725: }
                    726:
                    727: void
                    728: memio_free(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size)
                    729: {
                    730:        /* memio_unmap() does all that we need to do. */
                    731:        memio_unmap(t, bsh, size);
                    732: }

CVSweb <webmaster@jp.NetBSD.org>