|
|
1.1 ! root 1: #! /bin/sh ! 2: ! 3: # $Id: sparc-bus-auto.sh,v 1.1 2006/09/30 12:55:59 fredette Exp $ ! 4: ! 5: # ic/sparc/sparc-bus-auto.sh - automatically generates C code ! 6: # for SPARC bus emulation support: ! 7: ! 8: # ! 9: # Copyright (c) 2003, 2005 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: sparc-bus-auto.sh,v 1.1 2006/09/30 12:55:59 fredette Exp $"); ! 52: ! 53: /* it was easiest, but probably not the most correct, to reuse the ! 54: m68020 bus router, at least for the early SPARCs. there are ! 55: probably real differences between the m68020 bus router and the bus ! 56: router used by the MB89600, for example, but I don't have a ! 57: datasheet for the latter. the placement of devices in the Sun ! 58: 4/2x0 address space, however, hints that the two probably are very ! 59: similar. */ ! 60: ! 61: /* we use OP3, OP2, OP1, and OP0 to represent bytes of lesser ! 62: significance to more significance, respectively, matching Table 5-5 ! 63: in the MC68020 User's Manual (linear page 56 in my .ps copy). ! 64: ! 65: the Motorola OPn convention numbers bytes by decreasing ! 66: significance (OP2 is less significant than OP1), and since Motorola ! 67: CPUs are big-endian, this means that a higher numbered byte is ! 68: meant to go to a higher address, which is good, because we can then ! 69: use this to easily form indexes for TME_BUS_LANE_ROUTE, which ! 70: expects a higher numbered index to correspond to a higher address ! 71: in memory. ! 72: ! 73: however, since the same Motorola OPn convention always calls the ! 74: least significant byte of any value OP3, regardless of the total ! 75: size of the value, we need to adjust each OPn given the total ! 76: size of the value, so that OP3 in a 24-bit value means address + 2, ! 77: but OP3 in a 32-bit value means address + 3: */ ! 78: #define SIZ8_OP(n) ((n) - 3) ! 79: #define SIZ16_OP(n) ((n) - 2) ! 80: #define SIZ24_OP(n) ((n) - 1) ! 81: #define SIZ32_OP(n) ((n) - 0) ! 82: EOF ! 83: ! 84: # emit the 32-bit bus router: ! 85: if $header; then :; else ! 86: echo "" ! 87: echo "/* the 32-bit bus router used on the early SPARCs: */" ! 88: echo "static const tme_bus_lane_t tme_sparc32_router[TME_SPARC_BUS_ROUTER_SIZE(TME_BUS32_LOG2)] = {" ! 89: ! 90: # permute over maximum cycle size: ! 91: for transfer in 1 2 3 4; do ! 92: # these are real 68020 SIZ1 and SIZ0 bits: ! 93: case ${transfer} in ! 94: 1) transfer_bits="01" ;; ! 95: 2) transfer_bits="10" ;; ! 96: 3) transfer_bits="11" ;; ! 97: 4) transfer_bits="00" ;; ! 98: esac ! 99: ! 100: # permute over A1 and A0: ! 101: for address in 0 1 2 3; do ! 102: case $address in ! 103: 0) address_bits=00 ;; ! 104: 1) address_bits=01 ;; ! 105: 2) address_bits=10 ;; ! 106: 3) address_bits=11 ;; ! 107: esac ! 108: ! 109: # permute over the size of the responding device's port: ! 110: for port_size in 1 2 4; do ! 111: ! 112: # permute over the byte lane position of the responding device's port: ! 113: for port_pos in 0 1 2 3; do ! 114: ! 115: # get a string describing the byte lanes connected ! 116: # to this device. NB that the sparc 32-bit bus ! 117: # router assumes that 8-bit devices are always ! 118: # connected to D31-D24, and that 16-bit devices ! 119: # are always connected to D31-D24 and D23-D16, and ! 120: # cannot dynamically adapt to other ! 121: # configurations: ! 122: port_pos_end=`expr ${port_pos} + ${port_size}` ! 123: port_pos_lane=$port_pos ! 124: port_lanes="" ! 125: while test `expr ${port_pos_lane} \< ${port_pos_end}` = 1; do ! 126: port_lanes=" D"`expr \( \( ${port_pos_lane} + 1 \) \* 8 \) - 1`"-D"`expr ${port_pos_lane} \* 8`"${port_lanes}" ! 127: port_pos_lane=`expr ${port_pos_lane} + 1` ! 128: done ! 129: if test `expr ${port_pos_end} \> 4` = 1; then ! 130: port_lanes="${port_lanes} - invalid, array placeholder" ! 131: elif ( test $port_size = 1 && test $port_pos != 3 ) \ ! 132: || ( test $port_size = 2 && test $port_pos != 2 ); then ! 133: port_lanes="${port_lanes} - incorrect for 32-bit sparc" ! 134: fi ! 135: ! 136: # find the byte lane that would provide OP3. note ! 137: # that it may not exist (lane < 0), or that it may ! 138: # not be within the port: ! 139: opn=`expr 4 - ${transfer}` ! 140: opn_lane=`expr 3 - \( ${address} % ${port_size} \)` ! 141: op3_lane=`expr ${opn_lane} - \( 3 - ${opn} \)` ! 142: ! 143: echo "" ! 144: echo " /* [sparc] initiator maximum cycle size: "`expr ${transfer} \* 8`" bits" ! 145: echo " [sparc] initiator A1,A0: ${address_bits}" ! 146: echo " [gen] responder port size: "`expr ${port_size} \* 8`" bits" ! 147: echo " [gen] responder port least lane: ${port_pos} (lanes${port_lanes})" ! 148: echo " (code ${transfer}.${address}.${port_size}.${port_pos}, OP3 lane ${op3_lane}): */" ! 149: ! 150: # emit the bus router information for each lane: ! 151: for lane in 0 1 2 3; do ! 152: lane_warn= ! 153: ! 154: # if the sparc expects this byte lane to be connected ! 155: # to the device at this port size: ! 156: if test `expr ${lane} \< \( 4 - ${port_size} \)` = 0; then ! 157: ! 158: # if this lane is routed by the sparc when ! 159: # reading at this transfer size and ! 160: # address alignment: ! 161: opn=`expr 3 - \( ${lane} - ${op3_lane} \)` ! 162: if test `expr ${opn} \> 3` = 0 \ ! 163: && test `expr ${opn} \< \( 4 - ${transfer} \)` = 0; then ! 164: lane_read="OP(${opn})" ! 165: ! 166: # otherwise this lane isn't routed by the ! 167: # sparc when reading at this transfer size ! 168: # and address alignment: ! 169: else ! 170: lane_read="IGNORE" ! 171: fi ! 172: ! 173: # otherwise the sparc does not expect this byte ! 174: # lane to be connected to the device at this ! 175: # port size: ! 176: else ! 177: lane_read="IGNORE" ! 178: ! 179: # if this lane is connected to the device ! 180: # anyways, issue a warning: ! 181: if test `expr ${lane} \< ${port_pos}` = 0 \ ! 182: && test `expr ${lane} \< ${port_pos_end}` = 1; then ! 183: lane_warn=" | TME_BUS_LANE_WARN" ! 184: fi ! 185: fi ! 186: ! 187: # dispatch on how this lane is routed by the ! 188: # sparc when writing at this transfer size and ! 189: # address alignment: ! 190: case "${transfer_bits}${address_bits}.${lane}" in ! 191: 01??.3) lane_write="OP(3)" ;; ! 192: 01??.2) lane_write="OP(3)" ;; ! 193: 01??.1) lane_write="OP(3)" ;; ! 194: 01??.0) lane_write="OP(3)" ;; ! 195: ! 196: 10?0.3) lane_write="OP(2)" ;; ! 197: 10?0.2) lane_write="OP(3)" ;; ! 198: 10?0.1) lane_write="OP(2)" ;; ! 199: 10?0.0) lane_write="OP(3)" ;; ! 200: ! 201: 10?1.3) lane_write="OP(2)" ;; ! 202: 10?1.2) lane_write="OP(2)" ;; ! 203: 10?1.1) lane_write="OP(3)" ;; ! 204: 10?1.0) lane_write="OP(2)" ;; ! 205: ! 206: 1100.3) lane_write="OP(1)" ;; ! 207: 1100.2) lane_write="OP(2)" ;; ! 208: 1100.1) lane_write="OP(3)" ;; ! 209: 1100.0) lane_write="UNDEF" ;; # XXX this is supposed to be OP0, but we can't deal with that ! 210: ! 211: 1101.3) lane_write="OP(1)" ;; ! 212: 1101.2) lane_write="OP(1)" ;; ! 213: 1101.1) lane_write="OP(2)" ;; ! 214: 1101.0) lane_write="OP(3)" ;; ! 215: ! 216: 1110.3) lane_write="OP(1)" ;; ! 217: 1110.2) lane_write="OP(2)" ;; ! 218: 1110.1) lane_write="OP(1)" ;; ! 219: 1110.0) lane_write="OP(2)" ;; ! 220: ! 221: 1111.3) lane_write="OP(1)" ;; ! 222: 1111.2) lane_write="OP(1)" ;; ! 223: 1111.1) lane_write="OP(2)" ;; ! 224: 1111.0) lane_write="OP(1)" ;; ! 225: ! 226: 0000.3) lane_write="OP(0)" ;; ! 227: 0000.2) lane_write="OP(1)" ;; ! 228: 0000.1) lane_write="OP(2)" ;; ! 229: 0000.0) lane_write="OP(3)" ;; ! 230: ! 231: 0001.3) lane_write="OP(0)" ;; ! 232: 0001.2) lane_write="OP(0)" ;; ! 233: 0001.1) lane_write="OP(1)" ;; ! 234: 0001.0) lane_write="OP(2)" ;; ! 235: ! 236: 0010.3) lane_write="OP(0)" ;; ! 237: 0010.2) lane_write="OP(1)" ;; ! 238: 0010.1) lane_write="OP(0)" ;; ! 239: 0010.0) lane_write="OP(1)" ;; ! 240: ! 241: 0011.3) lane_write="OP(0)" ;; ! 242: 0011.2) lane_write="OP(0)" ;; ! 243: 0011.1) lane_write="OP(1)" ;; ! 244: 0011.0) lane_write="OP(0)" ;; ! 245: ! 246: esac ! 247: ! 248: # emit the comment for this lane: ! 249: echo -n " /* D"`expr \( \( ${lane} + 1 \) \* 8 \) - 1`"-D"`expr ${lane} \* 8`" */ " ! 250: ! 251: # if this port size/position combination is ! 252: # invalid, override everything and abort if ! 253: # this router entry is ever touched: ! 254: if test `expr ${port_pos_end} \> 4` = 1; then ! 255: echo "TME_BUS_LANE_ABORT," ! 256: else ! 257: if test $lane_read != "IGNORE"; then ! 258: if test $lane_read != $lane_write; then ! 259: echo "$PROG internal error: code ${transfer}.${address}.${port_size}.${port_pos}, reading $lane_read but writing $lane_write" 1>&2 ! 260: exit 1 ! 261: fi ! 262: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_read)" ! 263: elif test $lane_write = "UNDEF"; then ! 264: echo -n "TME_BUS_LANE_UNDEF" ! 265: else ! 266: echo -n "TME_BUS_LANE_ROUTE(SIZ"`expr ${transfer} \* 8`"_$lane_write) | TME_BUS_LANE_ROUTE_WRITE_IGNORE" ! 267: fi ! 268: echo "${lane_warn}," ! 269: fi ! 270: done ! 271: done ! 272: done ! 273: done ! 274: done ! 275: echo "};" ! 276: fi ! 277: ! 278: cat <<EOF ! 279: #undef SIZ8_OP ! 280: #undef SIZ16_OP ! 281: #undef SIZ24_OP ! 282: #undef SIZ32_OP ! 283: EOF ! 284: ! 285: # done: ! 286: exit 0
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.