|
|
1.1 ! root 1: #! /bin/sh ! 2: ! 3: # $Id: m68k-bus-auto.sh,v 1.2 2003/04/23 19:13:29 fredette Exp $ ! 4: ! 5: # ic/m68k/m68k-bus-auto.sh - automatically generates C code ! 6: # for m68k bus emulation support: ! 7: ! 8: # ! 9: # Copyright (c) 2003 Matt Fredette ! 10: # All rights reserved. ! 11: # ! 12: # Redistribution and use in source and binary forms, with or without ! 13: # modification, are permitted provided that the following conditions ! 14: # are met: ! 15: # 1. Redistributions of source code must retain the above copyright ! 16: # notice, this list of conditions and the following disclaimer. ! 17: # 2. Redistributions in binary form must reproduce the above copyright ! 18: # notice, this list of conditions and the following disclaimer in the ! 19: # documentation and/or other materials provided with the distribution. ! 20: # 3. All advertising materials mentioning features or use of this software ! 21: # must display the following acknowledgement: ! 22: # This product includes software developed by Matt Fredette. ! 23: # 4. The name of the author may not be used to endorse or promote products ! 24: # derived from this software without specific prior written permission. ! 25: # ! 26: # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ! 27: # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ! 28: # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ! 29: # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ! 30: # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ! 31: # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ! 32: # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 33: # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ! 34: # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ! 35: # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! 36: # POSSIBILITY OF SUCH DAMAGE. ! 37: # ! 38: ! 39: header=false ! 40: ! 41: for option ! 42: do ! 43: case $option in ! 44: --header) header=true ;; ! 45: esac ! 46: done ! 47: ! 48: PROG=`basename $0` ! 49: cat <<EOF ! 50: /* automatically generated by $PROG, do not edit! */ ! 51: _TME_RCSID("\$Id: m68k-bus-auto.sh,v 1.2 2003/04/23 19:13:29 fredette Exp $"); ! 52: ! 53: /* we use OP3, OP2, OP1, and OP0 to represent bytes of lesser ! 54: significance to more significance, respectively, matching Table 5-5 ! 55: in the MC68020 User's Manual (linear page 56 in my .ps copy). ! 56: ! 57: the Motorola OPn convention numbers bytes by decreasing ! 58: significance (OP2 is less significant than OP1), and since Motorola ! 59: CPUs are big-endian, this means that a higher numbered byte is ! 60: meant to go to a higher address, which is good, because we can then ! 61: use this to easily form indexes for TME_BUS_LANE_ROUTE, which ! 62: expects a higher numbered index to correspond to a higher address ! 63: in memory. ! 64: ! 65: however, since the same Motorola OPn convention always calls the ! 66: least significant byte of any value OP3, regardless of the total ! 67: size of the value, we need to adjust each OPn given the total ! 68: size of the value, so that OP3 in a 24-bit value means address + 2, ! 69: but OP3 in a 32-bit value means address + 3: */ ! 70: #define SIZ8_OP(n) ((n) - 3) ! 71: #define SIZ16_OP(n) ((n) - 2) ! 72: #define SIZ24_OP(n) ((n) - 1) ! 73: #define SIZ32_OP(n) ((n) - 0) ! 74: EOF ! 75: ! 76: # emit the 16-bit bus router: ! 77: if $header; then :; else ! 78: echo "" ! 79: echo "/* the 16-bit bus router used on the 68000 and 68010: */" ! 80: echo "const tme_bus_lane_t tme_m68k_router_16[TME_M68K_BUS_ROUTER_SIZE(TME_BUS16_LOG2)] = {" ! 81: ! 82: # permute over maximum cycle size: ! 83: for transfer in 1 2; do ! 84: ! 85: # permute over A0: ! 86: for address in 0 1; do ! 87: address_bits=$address ! 88: ! 89: # permute over the size of the responding device's port: ! 90: for port_size in 1 2; do ! 91: ! 92: # permute over the byte lane position of the responding device's port: ! 93: for port_pos in 0 1; do ! 94: ! 95: # get a string describing the byte lanes driven by ! 96: # this device: ! 97: port_pos_end=`expr ${port_pos} + ${port_size}` ! 98: port_pos_lane=$port_pos ! 99: port_lanes="" ! 100: while test `expr ${port_pos_lane} \< ${port_pos_end}` = 1; do ! 101: port_lanes=" D"`expr \( \( ${port_pos_lane} + 1 \) \* 8 \) - 1`"-D"`expr ${port_pos_lane} \* 8`"${port_lanes}" ! 102: port_pos_lane=`expr ${port_pos_lane} + 1` ! 103: done ! 104: if test `expr ${port_pos_end} \> 2` = 1; then ! 105: port_lanes="${port_lanes} - invalid, array placeholder" ! 106: elif test $transfer = 1 \ ! 107: && test $port_size = 1 \ ! 108: && test $port_pos != `expr 1 - ${address}`; then ! 109: port_lanes="${port_lanes} - incorrect for 16-bit m68k" ! 110: fi ! 111: ! 112: echo "" ! 113: echo " /* [m68k] initiator maximum cycle size: "`expr ${transfer} \* 8`" bits" ! 114: echo " [m68k] initiator A0: ${address_bits}" ! 115: echo " [gen] responding port size: "`expr ${port_size} \* 8`" bits" ! 116: echo " [gen] responding port least lane: ${port_pos} (lanes${port_lanes})" ! 117: echo " (code ${transfer}.${address}.${port_size}.${port_pos}): */" ! 118: ! 119: # emit the bus router information for each lane: ! 120: for lane in 0 1; do ! 121: ! 122: # dispatch: ! 123: lane_warn= ! 124: case "${transfer}:${address}:${lane}" in ! 125: 2:0:1) ! 126: lane_read="OP(2)" ! 127: lane_write="OP(2)" ! 128: ;; ! 129: 2:0:0) ! 130: lane_read="OP(3)" ! 131: lane_write="OP(3)" ! 132: ;; ! 133: 2:1:[01]) ! 134: lane_read="ABORT" ! 135: lane_write="ABORT" ! 136: ;; ! 137: 1:0:1 | 1:1:0) ! 138: lane_read="OP(3)" ! 139: lane_write="OP(3)" ! 140: ;; ! 141: 1:0:0 | 1:1:1) ! 142: lane_read="IGNORE" ! 143: lane_write="OP(3)" ! 144: if test $port_size = 1 \ ! 145: && test $port_pos != `expr 1 - ${address}`; then ! 146: lane_warn=" | TME_BUS_LANE_WARN" ! 147: fi ! 148: ;; ! 149: *) ! 150: echo "$PROG internal error: unhandled 16-bit bus case ${transfer}:${address}:${lane}" 1>&2 ! 151: exit 1 ! 152: ;; ! 153: esac ! 154: ! 155: # emit the comment for this lane: ! 156: echo -n " /* D"`expr \( \( ${lane} + 1 \) \* 8 \) - 1`"-D"`expr ${lane} \* 8`" */ " ! 157: ! 158: # if this port size/position combination is ! 159: # invalid, override everything and abort if ! 160: # this router entry is ever touched: ! 161: if test `expr ${port_pos_end} \> 2` = 1; then ! 162: echo "TME_BUS_LANE_ABORT," ! 163: else ! 164: if test $lane_read = "ABORT"; then ! 165: echo -n "TME_BUS_LANE_ABORT" ! 166: elif test $lane_read != "IGNORE"; then ! 167: if test $lane_read != $lane_write; then ! 168: echo "$PROG internal error: code ${transfer}:${address}:${lane}, reading $lane_read but writing $lane_write" 1>&2 ! 169: exit 1 ! 170: fi ! 171: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_read)" ! 172: else ! 173: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_write) | TME_BUS_LANE_ROUTE_WRITE_IGNORE" ! 174: fi ! 175: echo "${lane_warn}," ! 176: fi ! 177: done ! 178: done ! 179: done ! 180: done ! 181: done ! 182: echo "};" ! 183: fi ! 184: ! 185: # emit the 32-bit bus router: ! 186: if $header; then :; else ! 187: echo "" ! 188: echo "/* the 32-bit bus router used on the 68020 and 68030: */" ! 189: echo "static const tme_bus_lane_t tme_m68k_router_32[TME_M68K_BUS_ROUTER_SIZE(TME_BUS32_LOG2)] = {" ! 190: ! 191: # permute over maximum cycle size: ! 192: for transfer in 1 2 3 4; do ! 193: # these are real 68020 SIZ1 and SIZ0 bits: ! 194: case ${transfer} in ! 195: 1) transfer_bits="01" ;; ! 196: 2) transfer_bits="10" ;; ! 197: 3) transfer_bits="11" ;; ! 198: 4) transfer_bits="00" ;; ! 199: esac ! 200: ! 201: # permute over A1 and A0: ! 202: for address in 0 1 2 3; do ! 203: case $address in ! 204: 0) address_bits=00 ;; ! 205: 1) address_bits=01 ;; ! 206: 2) address_bits=10 ;; ! 207: 3) address_bits=11 ;; ! 208: esac ! 209: ! 210: # permute over the size of the responding device's port: ! 211: for port_size in 1 2 4; do ! 212: ! 213: # permute over the byte lane position of the responding device's port: ! 214: for port_pos in 0 1 2 3; do ! 215: ! 216: # get a string describing the byte lanes connected ! 217: # to this device. NB that the m68k 32-bit bus ! 218: # router assumes that 8-bit devices are always ! 219: # connected to D31-D24, and that 16-bit devices ! 220: # are always connected to D31-D24 and D23-D16, and ! 221: # cannot dynamically adapt to other ! 222: # configurations: ! 223: port_pos_end=`expr ${port_pos} + ${port_size}` ! 224: port_pos_lane=$port_pos ! 225: port_lanes="" ! 226: while test `expr ${port_pos_lane} \< ${port_pos_end}` = 1; do ! 227: port_lanes=" D"`expr \( \( ${port_pos_lane} + 1 \) \* 8 \) - 1`"-D"`expr ${port_pos_lane} \* 8`"${port_lanes}" ! 228: port_pos_lane=`expr ${port_pos_lane} + 1` ! 229: done ! 230: if test `expr ${port_pos_end} \> 4` = 1; then ! 231: port_lanes="${port_lanes} - invalid, array placeholder" ! 232: elif ( test $port_size = 1 && test $port_pos != 3 ) \ ! 233: || ( test $port_size = 2 && test $port_pos != 2 ); then ! 234: port_lanes="${port_lanes} - incorrect for 32-bit m68k" ! 235: fi ! 236: ! 237: # find the byte lane that would provide OP3. note ! 238: # that it may not exist (lane < 0), or that it may ! 239: # not be within the port: ! 240: opn=`expr 4 - ${transfer}` ! 241: opn_lane=`expr 3 - \( ${address} % ${port_size} \)` ! 242: op3_lane=`expr ${opn_lane} - \( 3 - ${opn} \)` ! 243: ! 244: echo "" ! 245: echo " /* [m68k] initiator maximum cycle size: "`expr ${transfer} \* 8`" bits" ! 246: echo " [m68k] initiator A1,A0: ${address_bits}" ! 247: echo " [gen] responder port size: "`expr ${port_size} \* 8`" bits" ! 248: echo " [gen] responder port least lane: ${port_pos} (lanes${port_lanes})" ! 249: echo " (code ${transfer}.${address}.${port_size}.${port_pos}, OP3 lane ${op3_lane}): */" ! 250: ! 251: # emit the bus router information for each lane: ! 252: for lane in 0 1 2 3; do ! 253: lane_warn= ! 254: ! 255: # if the m68k expects this byte lane to be connected ! 256: # to the device at this port size: ! 257: if test `expr ${lane} \< \( 4 - ${port_size} \)` = 0; then ! 258: ! 259: # if this lane is routed by the m68k when ! 260: # reading at this transfer size and ! 261: # address alignment: ! 262: opn=`expr 3 - \( ${lane} - ${op3_lane} \)` ! 263: if test `expr ${opn} \> 3` = 0 \ ! 264: && test `expr ${opn} \< \( 4 - ${transfer} \)` = 0; then ! 265: lane_read="OP(${opn})" ! 266: ! 267: # otherwise this lane isn't routed by the ! 268: # m68k when reading at this transfer size ! 269: # and address alignment: ! 270: else ! 271: lane_read="IGNORE" ! 272: fi ! 273: ! 274: # otherwise the m68k does not expect this byte ! 275: # lane to be connected to the device at this ! 276: # port size: ! 277: else ! 278: lane_read="IGNORE" ! 279: ! 280: # if this lane is connected to the device ! 281: # anyways, issue a warning: ! 282: if test `expr ${lane} \< ${port_pos}` = 0 \ ! 283: && test `expr ${lane} \< ${port_pos_end}` = 1; then ! 284: lane_warn=" | TME_BUS_LANE_WARN" ! 285: fi ! 286: fi ! 287: ! 288: # dispatch on how this lane is routed by the ! 289: # m68k when writing at this transfer size and ! 290: # address alignment: ! 291: case "${transfer_bits}${address_bits}.${lane}" in ! 292: 01??.3) lane_write="OP(3)" ;; ! 293: 01??.2) lane_write="OP(3)" ;; ! 294: 01??.1) lane_write="OP(3)" ;; ! 295: 01??.0) lane_write="OP(3)" ;; ! 296: ! 297: 10?0.3) lane_write="OP(2)" ;; ! 298: 10?0.2) lane_write="OP(3)" ;; ! 299: 10?0.1) lane_write="OP(2)" ;; ! 300: 10?0.0) lane_write="OP(3)" ;; ! 301: ! 302: 10?1.3) lane_write="OP(2)" ;; ! 303: 10?1.2) lane_write="OP(2)" ;; ! 304: 10?1.1) lane_write="OP(3)" ;; ! 305: 10?1.0) lane_write="OP(2)" ;; ! 306: ! 307: 1100.3) lane_write="OP(1)" ;; ! 308: 1100.2) lane_write="OP(2)" ;; ! 309: 1100.1) lane_write="OP(3)" ;; ! 310: 1100.0) lane_write="UNDEF" ;; # XXX this is supposed to be OP0, but we can't deal with that ! 311: ! 312: 1101.3) lane_write="OP(1)" ;; ! 313: 1101.2) lane_write="OP(1)" ;; ! 314: 1101.1) lane_write="OP(2)" ;; ! 315: 1101.0) lane_write="OP(3)" ;; ! 316: ! 317: 1110.3) lane_write="OP(1)" ;; ! 318: 1110.2) lane_write="OP(2)" ;; ! 319: 1110.1) lane_write="OP(1)" ;; ! 320: 1110.0) lane_write="OP(2)" ;; ! 321: ! 322: 1111.3) lane_write="OP(1)" ;; ! 323: 1111.2) lane_write="OP(1)" ;; ! 324: 1111.1) lane_write="OP(2)" ;; ! 325: 1111.0) lane_write="OP(1)" ;; ! 326: ! 327: 0000.3) lane_write="OP(0)" ;; ! 328: 0000.2) lane_write="OP(1)" ;; ! 329: 0000.1) lane_write="OP(2)" ;; ! 330: 0000.0) lane_write="OP(3)" ;; ! 331: ! 332: 0001.3) lane_write="OP(0)" ;; ! 333: 0001.2) lane_write="OP(0)" ;; ! 334: 0001.1) lane_write="OP(1)" ;; ! 335: 0001.0) lane_write="OP(2)" ;; ! 336: ! 337: 0010.3) lane_write="OP(0)" ;; ! 338: 0010.2) lane_write="OP(1)" ;; ! 339: 0010.1) lane_write="OP(0)" ;; ! 340: 0010.0) lane_write="OP(1)" ;; ! 341: ! 342: 0011.3) lane_write="OP(0)" ;; ! 343: 0011.2) lane_write="OP(0)" ;; ! 344: 0011.1) lane_write="OP(1)" ;; ! 345: 0011.0) lane_write="OP(0)" ;; ! 346: ! 347: esac ! 348: ! 349: # emit the comment for this lane: ! 350: echo -n " /* D"`expr \( \( ${lane} + 1 \) \* 8 \) - 1`"-D"`expr ${lane} \* 8`" */ " ! 351: ! 352: # if this port size/position combination is ! 353: # invalid, override everything and abort if ! 354: # this router entry is ever touched: ! 355: if test `expr ${port_pos_end} \> 4` = 1; then ! 356: echo "TME_BUS_LANE_ABORT," ! 357: else ! 358: if test $lane_read != "IGNORE"; then ! 359: if test $lane_read != $lane_write; then ! 360: echo "$PROG internal error: code ${transfer}.${address}.${port_size}.${port_pos}, reading $lane_read but writing $lane_write" 1>&2 ! 361: exit 1 ! 362: fi ! 363: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_read)" ! 364: elif test $lane_write = "UNDEF"; then ! 365: echo -n "TME_BUS_LANE_UNDEF" ! 366: else ! 367: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_write) | TME_BUS_LANE_ROUTE_WRITE_IGNORE" ! 368: fi ! 369: echo "${lane_warn}," ! 370: fi ! 371: done ! 372: done ! 373: done ! 374: done ! 375: done ! 376: echo "};" ! 377: fi ! 378: ! 379: cat <<EOF ! 380: #undef SIZ8_OP ! 381: #undef SIZ16_OP ! 382: #undef SIZ24_OP ! 383: #undef SIZ32_OP ! 384: EOF ! 385: ! 386: # done: ! 387: exit 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.