Annotation of tme/generic/bus-device-auto.sh, revision 1.1.1.1

1.1       root        1: #! /bin/sh
                      2: 
                      3: # $Id: bus-device-auto.sh,v 1.1 2004/03/28 23:38:28 fredette Exp $
                      4: 
                      5: # generic/bus-device-auto.sh - automatically generates C code for
                      6: # generic bus device support:
                      7: 
                      8: #
                      9: # Copyright (c) 2004 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: bus-device-auto.sh,v 1.1 2004/03/28 23:38:28 fredette Exp $");
                     52: EOF
                     53: 
                     54: if $header; then :; else
                     55:     cat <<EOF
                     56: 
                     57: /* this indexes an initiator bus router array for a device with a port size
                     58:    of 8 * (2 ^ siz_lg2) bits: */
                     59: #define TME_BUS_ROUTER_INIT_INDEX(siz_lg2, cycle_size, address) \\
                     60: (((                                                             \\
                     61:    /* by the maximum cycle size: */                             \\
                     62:    ((cycle_size) - 1)                                           \\
                     63:                                                                 \\
                     64:    /* by the address alignment: */                              \\
                     65:    << siz_lg2)                                                  \\
                     66:   + ((address) & ((1 << (siz_lg2)) - 1)))                       \\
                     67:                                                                 \\
                     68:  /* factor in the size of the generic bus router array: */      \\
                     69:  * TME_BUS_ROUTER_SIZE(siz_lg2))
                     70: 
                     71: /* this gives the number of entries that must be in a generic bus
                     72:    router array for a device with a bus size of 8 * (2 ^ siz_lg2)
                     73:    bits: */
                     74: #define TME_BUS_ROUTER_INIT_SIZE(siz_lg2)                       \\
                     75:   TME_BUS_ROUTER_INIT_INDEX(siz_lg2, (1 << (siz_lg2)) + 1, 0)
                     76: 
                     77: EOF
                     78: fi
                     79: 
                     80: # permute over initiator bus port width:
                     81: #
                     82: i_width=8
                     83: while test ${i_width} != 32; do
                     84:     i_width=`expr ${i_width} \* 2`
                     85: 
                     86:     # permute over initiator endianness:
                     87:     #
                     88:     for endian in b l; do
                     89:        if test ${endian} = b; then endian_what=big; else endian_what=little; fi
                     90: 
                     91:        # start the array:
                     92:        #
                     93:        echo ""
                     94:        echo "/* the ${i_width}-bit ${endian_what}-endian bus master bus router: */"
                     95:        what="const tme_bus_lane_t tme_bus_device_router_${i_width}e${endian}"
                     96:        if $header; then
                     97:            echo "extern ${what}[];"
                     98:            continue
                     99:        fi
                    100:        echo "${what}[TME_BUS_ROUTER_INIT_SIZE(TME_BUS${i_width}_LOG2)] = {"
                    101: 
                    102:        # permute over initiator maximum cycle size:
                    103:        #
                    104:        i_size=0
                    105:        while test `expr ${i_size} \< ${i_width}` = 1; do
                    106:            i_size=`expr ${i_size} + 8`
                    107: 
                    108:            # permute over initiator address offset:
                    109:            #
                    110:            i_offset=0
                    111:            while test `expr ${i_offset} \< ${i_width}` = 1; do
                    112: 
                    113:                # calculate the initiator least and greatest lanes:
                    114:                #
                    115:                placeholder=false
                    116:                if test ${endian} = b; then
                    117:                    i_lane_greatest=`expr -8 + ${i_width} - ${i_offset}`
                    118:                    i_lane_least=`expr 8 + ${i_lane_greatest} - ${i_size}`
                    119:                    if test `expr ${i_lane_least} \< 0` = 1; then
                    120:                        placeholder=true
                    121:                    fi
                    122:                else
                    123:                    i_lane_least=$i_offset
                    124:                    i_lane_greatest=`expr -8 + ${i_offset} + ${i_size}`
                    125:                    if test `expr ${i_lane_greatest} \>= ${i_width}` = 1; then
                    126:                        placeholder=true
                    127:                    fi
                    128:                fi
                    129: 
                    130:                # permute over responder bus port width:
                    131:                #
                    132:                r_width=4
                    133:                while test `expr ${r_width} \< ${i_width}` = 1; do
                    134:                    r_width=`expr ${r_width} \* 2`
                    135: 
                    136:                    # permute over responder bus port least lane:
                    137:                    #
                    138:                    r_lane_least=0
                    139:                    while test `expr ${r_lane_least} \< ${i_width}` = 1; do
                    140:                        r_lane_greatest=`expr -8 + ${r_lane_least} + ${r_width}`
                    141: 
                    142:                        # emit the initiator information:
                    143:                        #
                    144:                        echo ""
                    145:                        echo "  /* initiator maximum cycle size: ${i_size} bits"
                    146:                        echo "     initiator address offset: ${i_offset} bits"
                    147:                        if $placeholder; then
                    148:                            echo "     (a ${i_width}-bit initiator cannot request ${i_size} bits at an ${i_offset}-bit offset - this is an array placeholder)"
                    149:                        fi
                    150: 
                    151:                        # emit the responder information:
                    152:                        #
                    153:                        echo "     responder bus port size: ${r_width} bits"
                    154:                        echo -n "     responder port least lane: D"`expr ${r_lane_least} + 7`"-D${r_lane_least}"
                    155: 
                    156:                        # if the responder bus port greatest lane is
                    157:                        # greater than the initiator bus port width,
                    158:                        # part of the responder's port is outside of
                    159:                        # the initiator's port:
                    160:                        #
                    161:                        if test `expr ${r_lane_greatest} \>= ${i_width}` = 1; then
                    162:                            echo ""
                    163:                            echo -n "     (responder port not correctly positioned for this initiator)"
                    164:                        fi
                    165:                        echo ": */"
                    166: 
                    167:                        # permute over the lanes:
                    168:                        #
                    169:                        lane=0
                    170:                        if test ${endian} = b; then
                    171:                            route=`expr ${i_size} / 8`
                    172:                            route_increment=-1
                    173:                        else
                    174:                            route=-1
                    175:                            route_increment=1
                    176:                        fi
                    177:                        while test `expr ${lane} \< ${i_width}` = 1; do
                    178:                            echo -n "  /* D"`expr ${lane} + 7`"-D${lane} */     "
                    179: 
                    180:                            # see if this lane is on in the responder:
                    181:                            #
                    182:                            if test `expr ${lane} \>= ${r_lane_least}` = 1 \
                    183:                               && test `expr ${lane} \<= ${r_lane_greatest}` = 1; then
                    184:                                r_lane_on=true
                    185:                            else
                    186:                                r_lane_on=false
                    187:                            fi
                    188: 
                    189:                            # see if this lane is on in the initiator:
                    190:                            #
                    191:                            if test `expr ${lane} \>= ${i_lane_least}` = 1 \
                    192:                               && test `expr ${lane} \<= ${i_lane_greatest}` = 1; then
                    193:                                i_lane_on=true
                    194:                                route=`expr ${route} + ${route_increment}`
                    195:                            else
                    196:                                i_lane_on=false
                    197:                            fi
                    198: 
                    199:                            # if this is a placeholder entry:
                    200:                            #
                    201:                            if $placeholder; then
                    202:                                echo -n "TME_BUS_LANE_ABORT"
                    203: 
                    204:                            # otherwise, this is a real entry:
                    205:                            #
                    206:                            else
                    207:                                if $i_lane_on; then
                    208:                                    echo -n "TME_BUS_LANE_ROUTE(${route})"
                    209:                                    if $r_lane_on; then :; else
                    210:                                        echo -n " | TME_BUS_LANE_WARN"
                    211:                                    fi
                    212:                                else
                    213:                                    echo -n "TME_BUS_LANE_UNDEF"
                    214:                                fi
                    215:                            fi
                    216: 
                    217:                            echo ","
                    218:                            lane=`expr ${lane} + 8`
                    219:                        done
                    220: 
                    221:                        r_lane_least=`expr ${r_lane_least} + 8`
                    222:                    done
                    223:                done
                    224:                
                    225:                i_offset=`expr ${i_offset} + 8`
                    226:            done
                    227:        done
                    228: 
                    229:        # finish the array:
                    230:        #
                    231:        echo "};"
                    232:     done
                    233: 
                    234:     # permute over read/write:
                    235:     #
                    236:     for name in read write; do
                    237:        capname=`echo $name | tr a-z A-Z`
                    238:        if test $name = read; then 
                    239:            naming="reading"
                    240:            from="from"
                    241:            constbuffer=""
                    242:        else
                    243:            naming="writing"
                    244:            from="to"
                    245:            constbuffer="const "
                    246:        fi
                    247: 
                    248:        echo ""
                    249:        echo "/* the ${i_width}-bit bus master DMA ${name} function: */"
                    250:        if $header; then
                    251:            echo "int tme_bus_device_dma_${name}_${i_width} _TME_P((struct tme_bus_device *,"
                    252:            echo "                                       tme_bus_addr_t,"
                    253:            echo "                                       tme_bus_addr_t,"
                    254:            echo "                                       ${constbuffer}tme_uint8_t *,"
                    255:            echo "                                       unsigned int));"
                    256:            continue
                    257:        fi
                    258:        echo "int"
                    259:        echo "tme_bus_device_dma_${name}_${i_width}(struct tme_bus_device *bus_device,"
                    260:        echo "                           tme_bus_addr_t address_init,"
                    261:        echo "                           tme_bus_addr_t size,"
                    262:        echo "                           ${constbuffer}tme_uint8_t *buffer,"
                    263:        echo "                           unsigned int locks)"
                    264:        echo "{"
                    265:        echo "  struct tme_bus_tlb *tlb, tlb_local;"
                    266:        echo "  struct tme_bus_connection *conn_bus;"
                    267:        echo "  tme_bus_addr_t count_minus_one, count;"
                    268:        echo "  struct tme_bus_cycle cycle;"
                    269:        echo "  tme_bus_addr_t address_resp;"
                    270:        echo "  tme_bus_addr_t tlb_addr_last;"
                    271:        echo "  int shift;"
                    272:        echo "  int err;"
                    273:        echo ""
                    274:        echo "  /* assume no error: */"
                    275:        echo "  err = TME_OK;"
                    276:        echo ""
                    277:        echo "  /* loop while we have more bytes to ${name}: */"
                    278:        echo "  for (; err == TME_OK && size > 0; ) {"
                    279:        echo ""
                    280:        echo "    /* hash this address into a TLB entry: */"
                    281:        echo "    tlb = (*bus_device->tme_bus_device_tlb_hash)"
                    282:        echo "            (bus_device,"
                    283:        echo "             address_init,"
                    284:        echo "             TME_BUS_CYCLE_${capname});"
                    285:        echo ""
                    286:        echo "    /* if this TLB entry doesn't cover this address, or if it doesn't"
                    287:        echo "       allow ${naming}, reload it: */"
                    288:        echo "    tlb_addr_last = TME_ATOMIC_READ(tme_bus_addr_t, tlb->tme_bus_tlb_addr_last);"
                    289:        echo "    if (address_init < TME_ATOMIC_READ(tme_bus_addr_t, tlb->tme_bus_tlb_addr_first)"
                    290:        echo "        || address_init > tlb_addr_last"
                    291:        echo "        || (tlb->tme_bus_tlb_emulator_off_${name} == TME_EMULATOR_OFF_UNDEF"
                    292:        echo "            && !(tlb->tme_bus_tlb_cycles_ok & TME_BUS_CYCLE_${capname}))) {"
                    293:        echo ""
                    294:        echo "      /* reserve this TLB entry: */"
                    295:        echo "      tme_bus_tlb_reserve(tlb, &tlb_local);"
                    296:        echo "      tlb = &tlb_local;"
                    297:        echo ""
                    298:        echo "      /* get our bus connection: */"
                    299:        echo "      conn_bus = TME_ATOMIC_READ(struct tme_bus_connection *,"
                    300:        echo "                                 bus_device->tme_bus_device_connection);"
                    301:        echo ""
                    302:        echo "      /* unlock the device: */"
                    303:        echo "      (*bus_device->tme_bus_device_unlock)(bus_device, locks);"
                    304:        echo ""
                    305:        echo "      /* reload the TLB entry: */"
                    306:        echo "      err = (*conn_bus->tme_bus_tlb_fill)"
                    307:        echo "              (conn_bus,"
                    308:        echo "               tlb,"
                    309:        echo "               address_init,"
                    310:        echo "               TME_BUS_CYCLE_${capname});"
                    311:        echo ""
                    312:        echo "      /* lock the device: */"
                    313:        echo "      (*bus_device->tme_bus_device_lock)(bus_device, locks);"
                    314:        echo ""
                    315:        echo "      /* return if we couldn't fill the TLB entry: */"
                    316:        echo "      if (err != TME_OK) {"
                    317:        echo "        return (err);"
                    318:        echo "      }"
                    319:        echo ""
                    320:        echo "      /* the TLB entry must cover this address and allow ${naming}: */"
                    321:        echo "      tlb_addr_last = TME_ATOMIC_READ(tme_bus_addr_t, tlb->tme_bus_tlb_addr_last);"
                    322:        echo "      assert (address_init >= TME_ATOMIC_READ(tme_bus_addr_t, tlb->tme_bus_tlb_addr_first)"
                    323:        echo "              && address_init <= tlb_addr_last"
                    324:        echo "              && (tlb->tme_bus_tlb_emulator_off_${name} != TME_EMULATOR_OFF_UNDEF"
                    325:        echo "                  || (tlb->tme_bus_tlb_cycles_ok & TME_BUS_CYCLE_${capname})));"
                    326:        echo ""
                    327:        echo "      /* store the TLB entry: */"
                    328:        echo "      tme_bus_tlb_back(tlb);"
                    329:        echo "    }"
                    330:        echo ""
                    331:        echo "    /* if this TLB entry allows fast ${naming}: */"
                    332:        echo "    if (tlb->tme_bus_tlb_emulator_off_${name} != TME_EMULATOR_OFF_UNDEF) {"
                    333:        echo ""
                    334:        echo "      /* see how many bytes we can fast ${name} ${from} this TLB entry,"
                    335:        echo "         starting at this address: */"
                    336:        echo "      count_minus_one = (tlb_addr_last - address_init);"
                    337:        echo ""
                    338:        echo "      /* ${name} that many bytes or size bytes, whichever is smaller: */"
                    339:        echo "      count_minus_one = TME_MIN(count_minus_one,"
                    340:        echo "                                (size - 1));"
                    341:        echo "      count = count_minus_one + 1;"
                    342:        echo "      assert (count != 0);"
                    343:        echo ""
                    344:        echo "      /* do the fast ${name}: */"
                    345:        if test ${name} = read; then
                    346:            echo "      tme_memory_sequence_rdlock(tlb->tme_bus_tlb_rwlock);"
                    347:            echo "      memcpy(buffer,"
                    348:            echo "             (tlb->tme_bus_tlb_emulator_off_${name} + address_init), "
                    349:            echo "             count);"
                    350:        else
                    351:            echo "      tme_memory_sequence_wrlock(tlb->tme_bus_tlb_rwlock);"
                    352:            echo "      memcpy((tlb->tme_bus_tlb_emulator_off_${name} + address_init), "
                    353:            echo "             buffer,"
                    354:            echo "             count);"
                    355:        fi
                    356:        echo "      tme_memory_sequence_unlock(tlb->tme_bus_tlb_rwlock);"
                    357:        echo "    }"
                    358:        echo ""
                    359:        echo "    /* otherwise, we have to do a slow ${name}: */"
                    360:        echo "    else {"
                    361:        echo ""
                    362:        echo "      /* get the size of this bus cycle: */"
                    363:        echo "      count = (1 << TME_BUS${i_width}_LOG2);"
                    364:        echo "      count -= (address_init & (count - 1));"
                    365:        echo "      count = TME_MIN(count, size);"
                    366:        echo ""
                    367:        echo "      /* fill the cycle structure: */"
                    368:        echo "      cycle.tme_bus_cycle_type = TME_BUS_CYCLE_${capname};"
                    369:        echo "      cycle.tme_bus_cycle_size = count;"
                    370:        echo "      cycle.tme_bus_cycle_buffer = (tme_uint8_t *) buffer; /* XXX this breaks const */"
                    371:        echo "      cycle.tme_bus_cycle_buffer_increment = 1;"
                    372:        echo "      cycle.tme_bus_cycle_lane_routing"
                    373:        echo "        = (bus_device->tme_bus_device_router"
                    374:        echo "           + TME_BUS_ROUTER_INIT_INDEX(TME_BUS${i_width}_LOG2, count, address_init));"
                    375:        echo ""
                    376:        echo "      /* XXX this should come from a socket configuration: */"
                    377:        echo "      cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS${i_width}_LOG2);"
                    378:        echo ""
                    379:        echo "      /* form the physical address for the bus cycle handler: */"
                    380:        echo "      address_resp = tlb->tme_bus_tlb_addr_offset + address_init;"
                    381:        echo "      shift = tlb->tme_bus_tlb_addr_shift;"
                    382:        echo "      if (shift < 0) {"
                    383:        echo "        address_resp <<= (0 - shift);"
                    384:        echo "      }"
                    385:        echo "      else if (shift > 0) {"
                    386:        echo "        address_resp >>= shift;"
                    387:        echo "      }"
                    388:        echo "      cycle.tme_bus_cycle_address = address_resp;"
                    389:        echo ""
                    390:        echo "      /* unlock the device: */"
                    391:        echo "      (*bus_device->tme_bus_device_unlock)(bus_device, locks);"
                    392:        echo ""
                    393:        echo "      /* run the bus cycle: */"
                    394:        echo "      err = (*tlb->tme_bus_tlb_cycle)"
                    395:        echo "           (tlb->tme_bus_tlb_cycle_private, &cycle);"
                    396:        echo ""
                    397:        echo "      /* we don't support deadlocking: */"
                    398:        echo "      if (err == TME_EDEADLK) {"
                    399:        echo "        abort();"
                    400:        echo "      }"
                    401:        echo ""
                    402:        echo "      /* otherwise, any other error might be a bus error: */"
                    403:        echo "      else if (err != TME_OK) {"
                    404:        echo "        err = tme_bus_tlb_fault(tlb, &cycle, err);"
                    405:        echo "        assert (err != TME_OK);"
                    406:        echo "      }"
                    407:        echo ""
                    408:        echo "      /* lock the device: */"
                    409:        echo "      (*bus_device->tme_bus_device_lock)(bus_device, locks);"
                    410:        echo "    }"
                    411:        echo ""
                    412:        echo "    /* update the address, buffer, and size and continue: */"
                    413:        echo "    address_init += count;"
                    414:        echo "    buffer += count;"
                    415:        echo "    size -= count;"
                    416:        echo "  }"
                    417:        echo ""
                    418:        echo "  return (err);"
                    419:        echo "}"
                    420:     done
                    421: 
                    422: done
                    423: 
                    424: # done:
                    425: #
                    426: exit 0         

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.