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

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

unix.superglobalmegacorp.com

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