Annotation of tme/generic/bus-device-auto.sh, revision 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.