Annotation of tme/generic/bus-el.c, revision 1.1.1.2

1.1.1.2 ! root        1: /* $Id: bus-el.c,v 1.9 2003/07/29 18:19:12 fredette Exp $ */
1.1       root        2: 
1.1.1.2 ! root        3: /* generic/bus-el.c - a real generic bus element: */
1.1       root        4: 
                      5: /*
                      6:  * Copyright (c) 2003 Matt Fredette
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
                     19:  *      This product includes software developed by Matt Fredette.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     25:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     26:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
                     27:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
                     28:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     29:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
                     31:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
                     32:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     33:  * POSSIBILITY OF SUCH DAMAGE.
                     34:  */
                     35: 
                     36: #include <tme/common.h>
1.1.1.2 ! root       37: _TME_RCSID("$Id: bus-el.c,v 1.9 2003/07/29 18:19:12 fredette Exp $");
1.1       root       38: 
                     39: /* includes: */
                     40: #include <tme/generic/bus.h>
                     41: #include <stdlib.h>
                     42: #include <string.h>
                     43: 
                     44: /* macros: */
                     45: 
                     46: /* structures: */
                     47: 
                     48: /* this handles a bus connection signal edge: */
                     49: static int
                     50: _tme_bus_signal(struct tme_bus_connection *conn_bus_edger, unsigned int signal)
                     51: {
                     52:   struct tme_bus *bus;
                     53:   struct tme_bus_connection_int *conn_bus_int_edger;
                     54:   struct tme_bus_connection_int *conn_bus_int;
                     55:   unsigned int level_edge;
                     56:   struct tme_bus_connection *conn_bus;
                     57:   struct tme_bus_connection *conn_bus_other;
                     58:   int signal_asserted, need_propagate;
                     59:   unsigned int signal_index;
                     60:   tme_uint8_t signal_mask;
                     61:   int rc;
                     62:   int deadlocked;
                     63: 
                     64:   /* recover our bus: */
                     65:   bus = conn_bus_edger->tme_bus_connection.tme_connection_element->tme_element_private;
                     66:   conn_bus_int_edger = (struct tme_bus_connection_int *) conn_bus_edger;
                     67: 
                     68:   /* take out the level and edge: */
                     69:   level_edge = signal & (TME_BUS_SIGNAL_LEVEL_MASK
                     70:                         | TME_BUS_SIGNAL_EDGE);
                     71:   signal &= ~(TME_BUS_SIGNAL_LEVEL_MASK
                     72:              | TME_BUS_SIGNAL_EDGE);
                     73: 
                     74:   /* lock the bus for writing: */
                     75:   rc = tme_rwlock_timedwrlock(&bus->tme_bus_rwlock, TME_THREAD_TIMEDLOCK);
                     76:   if (TME_THREADS_ERRNO(rc) != TME_OK) {
                     77:     return (TME_THREADS_ERRNO(rc));
                     78:   }
                     79:   
                     80:   /* if this device doesn't know its interrupt signal, fix it: */
                     81:   if (signal == TME_BUS_SIGNAL_INT_UNSPEC) {
                     82:     signal = conn_bus_int_edger->tme_bus_connection_int_signal_int;
                     83:     if (signal == TME_BUS_SIGNAL_INT_UNSPEC) {
                     84:       /* this bus connection is misconfigured: */
                     85:       if (!conn_bus_int_edger->tme_bus_connection_int_logged_int) {
                     86:        conn_bus_int_edger->tme_bus_connection_int_logged_int = TRUE;
                     87:        /* XXX diagnostic */
                     88:        abort();
                     89:       }
                     90:       tme_rwlock_unlock(&bus->tme_bus_rwlock);
                     91:       return (TME_OK);
                     92:     }
                     93:   }
                     94: 
                     95:   /* assume we don't need to propagate this signal across the bus: */
                     96:   need_propagate = FALSE;
                     97: 
                     98:   /* if this is a random bus-specific signal, just propagate it: */
                     99:   if (TME_BUS_SIGNAL_IS_X(signal)) {
                    100:     need_propagate = TRUE;
                    101:   }
                    102: 
                    103:   /* otherwise, this is a generic bus signal: */
                    104:   else {
                    105:     
                    106:     /* decide whether the device is asserting or negating this signal: */
                    107:     /* XXX we currently assume that for all bus signals handled by this
                    108:        function, low implies assertion, and signals are always ORed
                    109:        together.  this could be configurable, possibly even per-signal: */
                    110:     signal_asserted = TRUE;
                    111:     switch (level_edge & TME_BUS_SIGNAL_LEVEL_MASK) {
                    112:     case TME_BUS_SIGNAL_LEVEL_LOW: 
                    113:     case TME_BUS_SIGNAL_LEVEL_ASSERTED:
                    114:       break;
                    115:     case TME_BUS_SIGNAL_LEVEL_HIGH: 
                    116:     case TME_BUS_SIGNAL_LEVEL_NEGATED:
                    117:       signal_asserted = FALSE;
                    118:       break;
                    119:     }
                    120:     level_edge = ((level_edge & TME_BUS_SIGNAL_EDGE)
                    121:                  | (signal_asserted
                    122:                     ? TME_BUS_SIGNAL_LEVEL_ASSERTED
                    123:                     : TME_BUS_SIGNAL_LEVEL_NEGATED));
                    124: 
                    125:     /* get the index and mask of this signal in signal byte arrays: */
                    126:     signal_index = TME_BUS_SIGNAL_BIT_INDEX(signal);
                    127:     signal_mask = TME_BUS_SIGNAL_BIT_MASK(signal);
                    128: 
                    129:     /* if this signal is being asserted: */
                    130:     if (signal_asserted) {
                    131: 
                    132:       /* if this device wasn't already asserting this signal: */
                    133:       if (!(conn_bus_int_edger->tme_bus_connection_int_signals[signal_index]
                    134:            & signal_mask)) {
                    135: 
                    136:        /* it is now asserting this signal: */
                    137:        conn_bus_int_edger->tme_bus_connection_int_signals[signal_index]
                    138:          |= signal_mask;
                    139:        bus->tme_bus_signal_asserts[TME_BUS_SIGNAL_WHICH(signal)]++;
                    140: 
                    141:        /* if this is the only device asserting this signal,
                    142:           propagate the change across the bus: */
                    143:        if (bus->tme_bus_signal_asserts[TME_BUS_SIGNAL_WHICH(signal)] == 1) {
                    144:          need_propagate = TRUE;
                    145:        }
                    146:       }
                    147: 
                    148:       /* otherwise, this device was already asserting this signal: */
                    149:       else {
                    150:        assert(bus->tme_bus_signal_asserts[TME_BUS_SIGNAL_WHICH(signal)] > 0);
                    151:       }
                    152:     }
                    153: 
                    154:     /* otherwise, this signal is being negated: */
                    155:     else {
                    156: 
                    157:       /* if this device was asserting this signal: */
                    158:       if (conn_bus_int_edger->tme_bus_connection_int_signals[signal_index]
                    159:          & signal_mask) {
                    160: 
                    161:        /* it is no longer asserting this signal: */
                    162:        conn_bus_int_edger->tme_bus_connection_int_signals[signal_index]
                    163:          &= ~signal_mask;
                    164:        assert(bus->tme_bus_signal_asserts[TME_BUS_SIGNAL_WHICH(signal)] > 0);
                    165:        bus->tme_bus_signal_asserts[TME_BUS_SIGNAL_WHICH(signal)]--;
                    166:       }
                    167: 
                    168:       /* we always propagate across the bus a signal that some device
                    169:         has negated, because often code will lazily only send
                    170:         negating edges, or other devices might still be asserting it,
                    171:         we assume these signals are always ORed together, and it
                    172:         kicks (even though this signal isn't edging) emulated
                    173:         circuitry that is meant to do things like interrupt
                    174:         arbitration, etc.: */
                    175:       if (bus->tme_bus_signal_asserts[TME_BUS_SIGNAL_WHICH(signal)] > 0) {
                    176:        level_edge = TME_BUS_SIGNAL_LEVEL_ASSERTED;
                    177:       }
                    178:       need_propagate = TRUE;
                    179:     }
                    180:   }
                    181: 
                    182:   /* if we're propagating this signal across the bus: */
                    183:   rc = TME_OK;
                    184:   if (need_propagate) {
                    185: 
                    186:     /* put the level and edge back in: */
                    187:     signal |= level_edge;
                    188: 
                    189:     /* assume that we won't deadlock: */
                    190:     deadlocked = FALSE;
                    191: 
                    192:     /* propagate the signal to each connection to the bus: */
                    193:     for (conn_bus_int = bus->tme_bus_connections;
                    194:         conn_bus_int != NULL;
                    195:         conn_bus_int =
                    196:           (struct tme_bus_connection_int *) 
                    197:           conn_bus_int->tme_bus_connection_int
                    198:           .tme_bus_connection
                    199:           .tme_connection_next) {
                    200:       conn_bus = &conn_bus_int->tme_bus_connection_int;
                    201:       conn_bus_other = 
                    202:        (struct tme_bus_connection *) 
                    203:        conn_bus->tme_bus_connection.tme_connection_other;
                    204:       
                    205:       /* skip this device if it edged the line to begin with: */
                    206:       if (conn_bus == conn_bus_edger) {
                    207:        continue;
                    208:       }
                    209: 
                    210:       /* skip this device if it doesn't care about bus signals: */
                    211:       if (conn_bus_other->tme_bus_signal == NULL) {
                    212:        continue;
                    213:       }
                    214: 
                    215:       /* give the edge to this connection: */
                    216:       rc =  (*conn_bus_other->tme_bus_signal)(conn_bus_other, signal);
                    217: 
                    218:       /* if we deadlocked, remember to tell the caller: */
                    219:       if (rc == TME_EDEADLK) {
                    220:        deadlocked = TRUE;
                    221:       }
                    222:     }
                    223:     rc = (deadlocked ? TME_EDEADLK : TME_OK);
                    224:   }
                    225: 
                    226:   /* unlock the bus: */
                    227:   tme_rwlock_unlock(&bus->tme_bus_rwlock);
                    228: 
                    229:   /* done: */
                    230:   return (rc);
                    231: }
                    232:                              
                    233: /* this handles a bus interrupt acknowledge: */
                    234: static int
                    235: _tme_bus_intack(struct tme_bus_connection *conn_bus_acker, unsigned int signal, int *vector)
                    236: {
                    237:   struct tme_bus *bus;
                    238:   struct tme_bus_connection_int *conn_bus_int;
                    239:   struct tme_bus_connection *conn_bus;
                    240:   struct tme_bus_connection *conn_bus_other;
                    241:   unsigned int signal_index;
                    242:   tme_uint8_t signal_mask;
                    243:   int rc;
                    244: 
                    245:   /* recover our bus: */
                    246:   bus = conn_bus_acker->tme_bus_connection.tme_connection_element->tme_element_private;
                    247: 
                    248:   /* get rid of any level and edge: */
                    249:   signal &= ~(TME_BUS_SIGNAL_LEVEL_MASK
                    250:              | TME_BUS_SIGNAL_EDGE);
                    251: 
                    252:   /* this must be an interrupt signal: */
                    253:   assert(TME_BUS_SIGNAL_IS_INT(signal));
                    254: 
                    255:   /* lock the bus for writing: */
                    256:   rc = tme_rwlock_timedwrlock(&bus->tme_bus_rwlock, TME_THREAD_TIMEDLOCK);
                    257:   if (TME_THREADS_ERRNO(rc) != TME_OK) {
                    258:     return (TME_THREADS_ERRNO(rc));
                    259:   }
                    260:   
                    261:   /* get the index and mask of this signal in signal byte arrays: */
                    262:   signal_index = TME_BUS_SIGNAL_BIT_INDEX(signal);
                    263:   signal_mask = TME_BUS_SIGNAL_BIT_MASK(signal);
                    264: 
                    265:   /* find the first connection to the bus that is asserting this
                    266:      interrupt signal.  if no connection is asserting the signal,
                    267:      return ENOENT: */
                    268:   rc = ENOENT;
                    269:   for (conn_bus_int = bus->tme_bus_connections;
                    270:        conn_bus_int != NULL;
                    271:        conn_bus_int =
                    272:         (struct tme_bus_connection_int *) 
                    273:         conn_bus_int->tme_bus_connection_int
                    274:         .tme_bus_connection
                    275:         .tme_connection_next) {
                    276:     conn_bus = &conn_bus_int->tme_bus_connection_int;
                    277:     conn_bus_other = 
                    278:       (struct tme_bus_connection *) 
                    279:       conn_bus->tme_bus_connection.tme_connection_other;
                    280:     
                    281:     /* if this device is asserting this interrupt signal: */
                    282:     if (conn_bus_int->tme_bus_connection_int_signals[signal_index]
                    283:        & signal_mask) {
                    284: 
                    285:       /* if this device doesn't acknowledge interrupts, 
                    286:         return an undefined vector: */
                    287:       if (conn_bus_other->tme_bus_intack == NULL) {
                    288:        *vector = TME_BUS_INTERRUPT_VECTOR_UNDEF;
                    289:        rc = TME_OK;
                    290:       }
                    291: 
                    292:       /* otherwise, run the interrupt acknowledge with this connection: */
                    293:       else {
                    294:        rc = (*conn_bus_other->tme_bus_intack)(conn_bus_other, signal, vector);
                    295:       }
                    296: 
                    297:       /* stop: */
                    298:       break;
                    299:     }
                    300:   }
                    301: 
                    302:   /* unlock the bus: */
                    303:   tme_rwlock_unlock(&bus->tme_bus_rwlock);
                    304: 
                    305:   /* done: */
                    306:   return (rc);
                    307: }
                    308: 
                    309: static int
                    310: _tme_bus_fault(void *junk0, struct tme_bus_cycle *junk1)
                    311: {
                    312:   return (ENOENT);
                    313: }
                    314: 
                    315: /* this fills a TLB entry: */
                    316: static int
                    317: _tme_bus_tlb_fill(struct tme_bus_connection *conn_bus_asker, 
                    318:                  struct tme_bus_tlb *tlb,
                    319:                  tme_bus_addr_t address, 
                    320:                  unsigned int cycles)
                    321: {
                    322:   struct tme_bus *bus;
                    323:   struct tme_bus_connection_int *conn_int;
                    324:   int rc;
                    325: 
                    326:   /* recover our bus and our connection to the asker: */
                    327:   bus = conn_bus_asker->tme_bus_connection.tme_connection_element->tme_element_private;
                    328:   conn_int = (struct tme_bus_connection_int *) conn_bus_asker;
                    329: 
                    330:   /* put our fault handler in the TLB entry: */
                    331:   tlb->tme_bus_tlb_cycle_private = NULL;
                    332:   tlb->tme_bus_tlb_cycle = _tme_bus_fault;
                    333: 
                    334:   /* lock the bus for reading: */
                    335:   rc = tme_rwlock_timedrdlock(&bus->tme_bus_rwlock, TME_THREAD_TIMEDLOCK);
                    336:   if (TME_THREADS_ERRNO(rc) != TME_OK) {
                    337:     return (TME_THREADS_ERRNO(rc));
                    338:   }
                    339: 
                    340:   /* call the generic bus support function: */
                    341:   rc = tme_bus_tlb_fill(bus,
                    342:                        conn_int,
                    343:                        tlb, address, cycles);
                    344: 
                    345:   /* unlock the bus: */
                    346:   tme_rwlock_unlock(&bus->tme_bus_rwlock);
                    347: 
                    348:   /* done: */
                    349:   return (rc);
                    350: }
                    351: 
                    352: /* this allocates a new TLB set: */
                    353: static int
                    354: _tme_bus_tlb_set_allocate(struct tme_bus_connection *conn_bus_asker,
                    355:                          unsigned int count, unsigned int sizeof_one, 
                    356:                          TME_ATOMIC_POINTER_TYPE(struct tme_bus_tlb **) _tlbs)
                    357: {
                    358:   struct tme_bus *bus;
                    359:   struct tme_bus_connection_int *conn_int;
                    360:   int rc;
                    361: 
                    362:   /* recover our bus and our connection to the asker: */
                    363:   bus = conn_bus_asker->tme_bus_connection.tme_connection_element->tme_element_private;
                    364:   conn_int = (struct tme_bus_connection_int *) conn_bus_asker;
                    365: 
                    366:   /* lock the bus for reading: */
                    367:   rc = tme_rwlock_timedrdlock(&bus->tme_bus_rwlock, TME_THREAD_TIMEDLOCK);
                    368:   if (TME_THREADS_ERRNO(rc) != TME_OK) {
                    369:     return (TME_THREADS_ERRNO(rc));
                    370:   }
                    371: 
                    372:   /* call the generic bus support function: */
                    373:   rc = tme_bus_tlb_set_allocate(bus,
                    374:                                conn_int,
                    375:                                count, sizeof_one, 
                    376:                                _tlbs);
                    377: 
                    378:   /* unlock the bus: */
                    379:   tme_rwlock_unlock(&bus->tme_bus_rwlock);
                    380: 
                    381:   /* done: */
                    382:   return (rc);
                    383: }
                    384: 
                    385: /* this scores a new connection: */
                    386: static int
                    387: _tme_bus_connection_score(struct tme_connection *conn, unsigned int *_score)
                    388: {
                    389:   struct tme_bus *bus;
                    390:   struct tme_bus_connection_int *conn_int;
                    391:   int rc, ok;
                    392: 
                    393:   /* both sides must be generic bus connections: */
                    394:   assert(conn->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                    395:   assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                    396: 
                    397:   /* recover our bus and our internal connection side: */
                    398:   bus = conn->tme_connection_element->tme_element_private;
                    399:   conn_int = (struct tme_bus_connection_int *) conn;
                    400: 
                    401:   /* lock the bus for reading: */
                    402:   rc = tme_rwlock_timedrdlock(&bus->tme_bus_rwlock, TME_THREAD_TIMEDLOCK);
                    403:   if (TME_THREADS_ERRNO(rc) != TME_OK) {
                    404:     return (TME_THREADS_ERRNO(rc));
                    405:   }
                    406:   
                    407:   /* call the generic bus support function: */
                    408:   ok = tme_bus_connection_ok(bus,
                    409:                             conn_int);
                    410: 
                    411:   /* unlock the bus: */
                    412:   tme_rwlock_unlock(&bus->tme_bus_rwlock);
                    413: 
                    414:   /* return the score: */
                    415:   *_score = (ok ? 1 : 0);
                    416:   return (TME_OK);
                    417: }
                    418: 
                    419: /* this makes a new connection: */
                    420: static int
                    421: _tme_bus_connection_make(struct tme_connection *conn, unsigned int state)
                    422: {
                    423:   struct tme_bus *bus;
                    424:   struct tme_bus_connection_int *conn_int;
                    425:   int rc;
                    426: 
                    427:   /* both sides must be generic bus connections: */
                    428:   assert(conn->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                    429:   assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                    430: 
                    431:   /* recover our bus and our internal connection side: */
                    432:   bus = conn->tme_connection_element->tme_element_private;
                    433:   conn_int = (struct tme_bus_connection_int *) conn;
                    434:   
                    435:   /* lock the bus for writing: */
                    436:   rc = tme_rwlock_timedwrlock(&bus->tme_bus_rwlock, TME_THREAD_TIMEDLOCK);
                    437:   if (TME_THREADS_ERRNO(rc) != TME_OK) {
                    438:     return (TME_THREADS_ERRNO(rc));
                    439:   }
                    440: 
                    441:   /* call the generic bus support function: */
                    442:   rc = tme_bus_connection_make(bus,
                    443:                               conn_int,
                    444:                               state);
                    445: 
                    446:   /* unlock the bus: */
                    447:   tme_rwlock_unlock(&bus->tme_bus_rwlock);
                    448: 
                    449:   return (rc);
                    450: }
                    451: 
                    452: /* this breaks a connection: */
                    453: static int 
                    454: _tme_bus_connection_break(struct tme_connection *conn, unsigned int state)
                    455: {
                    456:   abort();
                    457: }
                    458: 
                    459: /* this returns the new connections possible: */
                    460: static int
                    461: _tme_bus_connections_new(struct tme_element *element,
                    462:                         const char * const *args,
                    463:                         struct tme_connection **_conns,
                    464:                         char **_output)
                    465: {
                    466:   const struct tme_bus *bus;
                    467:   struct tme_bus_connection_int *conn_int;
                    468:   struct tme_bus_connection *conn_bus;
                    469:   struct tme_connection *conn;
                    470:   int ipl;
                    471:   int arg_i;
                    472:   int usage;
                    473: 
                    474:   /* recover our bus.  we only read the address mask, so we don't lock
                    475:      the rwlock: */
                    476:   bus = element->tme_element_private;
                    477: 
                    478:   /* allocate the new connection side: */
                    479:   conn_int = tme_new0(struct tme_bus_connection_int, 1);
                    480:   conn_bus = &conn_int->tme_bus_connection_int;
                    481:   conn = &conn_bus->tme_bus_connection;
                    482: 
                    483:   /* loop reading our arguments: */
                    484:   usage = FALSE;
                    485:   arg_i = 1;
                    486:   for (;;) {
                    487: 
                    488:     /* the address of this connection: */
                    489:     if (TME_ARG_IS(args[arg_i + 0], "addr")) {
                    490:       conn_int->tme_bus_connection_int_addressable = TRUE;
                    491:       conn_int->tme_bus_connection_int_address = tme_bus_addr_parse_any(args[arg_i + 1], &usage);
                    492:       if (usage
                    493:          || (conn_int->tme_bus_connection_int_address
                    494:              > bus->tme_bus_address_mask)) {
                    495:        usage = TRUE;
                    496:        break;
                    497:       }
                    498:       arg_i += 2;
                    499:     }
                    500: 
                    501:     /* the interrupt signal for this connection: */
                    502:     else if (TME_ARG_IS(args[arg_i + 0], "ipl")
                    503:             && args[arg_i + 1] != NULL
                    504:             && (ipl = atoi(args[arg_i + 1])) > 0) {
                    505:       conn_int->tme_bus_connection_int_signal_int = TME_BUS_SIGNAL_INT(ipl);
                    506:       arg_i += 2;
                    507:     }
                    508: 
                    509:     /* if we've run out of arguments: */
                    510:     else if (args[arg_i + 0] == NULL) {
                    511:       break;
                    512:     }
                    513: 
                    514:     /* this is a bad argument: */
                    515:     else {
                    516:       tme_output_append_error(_output,
                    517:                              "%s %s, ",
                    518:                              args[arg_i],
                    519:                              _("unexpected"));
                    520:       usage = TRUE;
                    521:       break;
                    522:     }
                    523:   }
                    524: 
                    525:   if (usage) {
                    526:     tme_output_append_error(_output, 
                    527:                            "%s %s [ addr %s ] [ ipl %s ]",
                    528:                            _("usage:"),
                    529:                            args[0],
                    530:                            _("BUS-ADDRESS"),
                    531:                            _("INTERRUPT-LEVEL"));
                    532:     tme_free(conn_int);
                    533:     return (EINVAL);
                    534:   }
                    535: 
                    536:   /* fill in the bus connection: */
1.1.1.2 ! root      537:   conn_bus->tme_bus_subregions.tme_bus_subregion_address_first
        !           538:     = 0;
        !           539:   conn_bus->tme_bus_subregions.tme_bus_subregion_address_last
        !           540:     = bus->tme_bus_address_mask;
        !           541:   conn_bus->tme_bus_subregions.tme_bus_subregion_next
        !           542:     = NULL;
1.1       root      543:   conn_bus->tme_bus_signal = _tme_bus_signal;
                    544:   conn_bus->tme_bus_intack = _tme_bus_intack;
                    545:   conn_bus->tme_bus_tlb_set_allocate = _tme_bus_tlb_set_allocate;
                    546:   conn_bus->tme_bus_tlb_fill = _tme_bus_tlb_fill;
                    547: 
                    548:   /* fill in the generic connection: */
                    549:   conn->tme_connection_next = *_conns;
                    550:   conn->tme_connection_type = TME_CONNECTION_BUS_GENERIC;
                    551:   conn->tme_connection_score = _tme_bus_connection_score;
                    552:   conn->tme_connection_make = _tme_bus_connection_make;
                    553:   conn->tme_connection_break = _tme_bus_connection_break;
                    554:   
                    555:   /* return the new connection side: */
                    556:   *_conns = conn;
                    557:   return (TME_OK);
                    558: }
                    559: 
                    560: /* this creates a new bus element: */
                    561: TME_ELEMENT_SUB_NEW_DECL(tme_generic,bus) {
                    562:   struct tme_bus *bus;
                    563:   tme_bus_addr_t bus_size;
                    564:   int failed;
                    565: 
                    566:   /* our arguments must include the bus size, and the
                    567:      bus size must be a power of two: */
                    568:   failed = TRUE;
                    569:   bus_size = 0;
                    570:   if (TME_ARG_IS(args[1], "size")) {
                    571:     bus_size = tme_bus_addr_parse_any(args[2], &failed);
                    572:     if (bus_size & (bus_size - 1)) {
                    573:       failed = TRUE;
                    574:     }
                    575:   }
                    576:   if (failed) {
                    577:     tme_output_append_error(_output,
                    578:                            "%s %s size %s",
                    579:                            _("usage:"),
                    580:                            args[0],
                    581:                            _("SIZE"));
                    582:     return (EINVAL);
                    583:   }
                    584: 
                    585:   /* allocate and initialize the new bus: */
                    586:   bus = tme_new0(struct tme_bus, 1);
                    587:   tme_rwlock_init(&bus->tme_bus_rwlock);
                    588:   bus->tme_bus_address_mask = bus_size - 1;
                    589:   bus->tme_bus_addressables_count = 0;
                    590:   bus->tme_bus_addressables_size = 1;
1.1.1.2 ! root      591:   bus->tme_bus_addressables = tme_new(struct tme_bus_addressable,
1.1       root      592:                                      bus->tme_bus_addressables_size);
                    593: 
                    594:   /* fill the element: */
                    595:   element->tme_element_private = bus;
                    596:   element->tme_element_connections_new = _tme_bus_connections_new;
                    597: 
                    598:   return (TME_OK);
                    599: }

unix.superglobalmegacorp.com

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