Annotation of tme/generic/bus-device.c, revision 1.1.1.5

1.1.1.5 ! root        1: /* $Id: bus-device.c,v 1.10 2009/08/28 01:23:44 fredette Exp $ */
1.1       root        2: 
1.1.1.2   root        3: /* generic/bus-device.c - implementation of a generic bus device support: */
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.5 ! root       37: _TME_RCSID("$Id: bus-device.c,v 1.10 2009/08/28 01:23:44 fredette Exp $");
1.1       root       38: 
                     39: /* includes: */
                     40: #include <tme/generic/bus-device.h>
                     41: 
1.1.1.3   root       42: /* include the automatically-generated bus-device functions: */
                     43: #include "bus-device-auto.c"
                     44: 
1.1.1.5 ! root       45: /* this adds a generic bus TLB set: */
        !            46: int
        !            47: tme_bus_device_tlb_set_add(struct tme_bus_device *bus_device,
        !            48:                           unsigned long tlb_count,
        !            49:                           struct tme_bus_tlb *tlb)
        !            50: {
        !            51:   struct tme_bus_tlb_set_info tlb_set_info;
        !            52:   struct tme_token *token;
        !            53:   struct tme_bus_connection *conn_bus;
        !            54:   int rc;
        !            55: 
        !            56:   /* make the TLB set information, and allocate a token for each TLB
        !            57:      entry: */
        !            58:   assert (tlb_count > 0);
        !            59:   memset(&tlb_set_info, 0, sizeof(tlb_set_info));
        !            60:   tlb_set_info.tme_bus_tlb_set_info_token0 = tme_new(struct tme_token, tlb_count);
        !            61:   tlb_set_info.tme_bus_tlb_set_info_token_stride = sizeof(struct tme_token);
        !            62:   tlb_set_info.tme_bus_tlb_set_info_token_count = tlb_count;
        !            63:   tlb_set_info.tme_bus_tlb_set_info_bus_context = NULL;
        !            64: 
        !            65:   /* connect each TLB entry with its token: */
        !            66:   token = tlb_set_info.tme_bus_tlb_set_info_token0;
        !            67:   do {
        !            68:     tme_token_init(token);
        !            69:     tlb->tme_bus_tlb_token = token;
        !            70:     tlb++;
        !            71:     token++;
        !            72:   } while (--tlb_count);
        !            73: 
        !            74:   /* get our bus connection: */
        !            75:   conn_bus
        !            76:     = tme_memory_atomic_pointer_read(struct tme_bus_connection *,
        !            77:                                     bus_device->tme_bus_device_connection,
        !            78:                                     &bus_device->tme_bus_device_connection_rwlock);
        !            79: 
        !            80:   /* add the TLB set: */
        !            81:   rc
        !            82:     = ((*conn_bus->tme_bus_tlb_set_add)
        !            83:        (conn_bus,
        !            84:        &tlb_set_info));
        !            85:   return (rc);
        !            86: }
        !            87: 
1.1       root       88: /* this scores a connection: */
                     89: int
                     90: tme_bus_device_connection_score(struct tme_connection *conn, unsigned int *_score)
                     91: {
                     92:   struct tme_bus_device *device;
                     93:   struct tme_bus_connection *conn_bus_other_old;
                     94:   struct tme_bus_connection *conn_bus_other_new;
                     95: 
                     96:   /* recover our device: */
                     97:   device = conn->tme_connection_element->tme_element_private;
                     98: 
                     99:   /* both sides must be generic bus connections: */
                    100:   assert(conn->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                    101:   assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                    102: 
                    103:   /* a simple bus device can have multiple connections, but they all
                    104:      must be from the same bus.  the only way we check that is by
                    105:      comparing elements: */
1.1.1.4   root      106:   conn_bus_other_old
                    107:     = tme_memory_atomic_pointer_read(struct tme_bus_connection *,
                    108:                                     device->tme_bus_device_connection,
                    109:                                     &device->tme_bus_device_connection_rwlock);
1.1       root      110:   conn_bus_other_new = (struct tme_bus_connection *) conn->tme_connection_other;
                    111:   if (conn_bus_other_old != NULL
                    112:       && (conn_bus_other_old->tme_bus_connection.tme_connection_element
                    113:          != conn_bus_other_new->tme_bus_connection.tme_connection_element)) {
                    114:     *_score = 0;
                    115:     return (TME_OK);
                    116:   }
                    117: 
                    118:   /* otherwise, this is our first connection or another connection to
                    119:      the same element.  note that there's no good way to differentiate
                    120:      a connection to a bus from a connection to just another chip, so
                    121:      we always return a nonzero score here: */
                    122:   *_score = 1;
                    123:   return (TME_OK);
                    124: }
                    125: 
                    126: /* this makes a new connection: */
                    127: int
                    128: tme_bus_device_connection_make(struct tme_connection *conn, unsigned int state)
                    129: {
                    130:   struct tme_bus_device *device;
                    131: 
                    132:   /* recover our device: */
                    133:   device = conn->tme_connection_element->tme_element_private;
                    134: 
                    135:   /* both sides must be generic bus connections: */
                    136:   assert(conn->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                    137:   assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                    138: 
                    139:   /* simple bus devices are always set up to answer calls across the
                    140:      connection, so we only have to do work when the connection
                    141:      has gone full, namely taking the other side of the
                    142:      connection: */
                    143:   if (state == TME_CONNECTION_FULL) {
                    144: 
                    145:     /* save our connection: */
1.1.1.4   root      146:     tme_memory_atomic_pointer_write(struct tme_bus_connection *,
                    147:                                    device->tme_bus_device_connection,
                    148:                                    (struct tme_bus_connection *) conn->tme_connection_other,
                    149:                                    &device->tme_bus_device_connection_rwlock);
1.1       root      150:   }
                    151: 
                    152:   return (TME_OK);
                    153: }
                    154: 
                    155: /* this breaks a connection: */
                    156: int
                    157: tme_bus_device_connection_break(struct tme_connection *conn, unsigned int state)
                    158: {
                    159:   abort();
                    160: }
                    161: 
                    162: static int
                    163: _tme_bus_device_signal(struct tme_bus_connection *conn_bus, unsigned int signal)
                    164: {
                    165:   struct tme_bus_device *device;
                    166:   device = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private;
                    167:   return ((*device->tme_bus_device_signal)(device, signal));
                    168: }
                    169: 
                    170: static int
                    171: _tme_bus_device_intack(struct tme_bus_connection *conn_bus, unsigned int signal, int *vector)
                    172: {
                    173:   struct tme_bus_device *device;
                    174:   device = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private;
                    175:   return ((*device->tme_bus_device_intack)(device, signal, vector));
                    176: }
                    177: 
                    178: static int
                    179: _tme_bus_device_tlb_fill(struct tme_bus_connection *conn_bus, struct tme_bus_tlb *tlb,
                    180:                         tme_bus_addr_t address, unsigned int cycles)
                    181: {
                    182:   struct tme_bus_device *device;
                    183:   device = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private;
                    184:   return ((*device->tme_bus_device_tlb_fill)(device, tlb, address, cycles));
                    185: }
                    186: 
                    187: /* this makes a new connection side for a simple bus device: */
                    188: int
                    189: tme_bus_device_connections_new(struct tme_element *element,
                    190:                               const char * const *args,
                    191:                               struct tme_connection **_conns,
                    192:                               char **_output)
                    193: {
                    194:   struct tme_bus_device *device;
                    195:   struct tme_bus_connection *conn_bus;
                    196:   struct tme_connection *conn;
                    197: 
                    198:   /* recover our device: */
                    199:   device = (struct tme_bus_device *) element->tme_element_private;
                    200: 
                    201:   /* create our side of a generic bus connection: */
                    202:   conn_bus = tme_new0(struct tme_bus_connection, 1);
                    203:   conn = &conn_bus->tme_bus_connection;
                    204: 
                    205:   /* fill in the generic connection: */
                    206:   conn->tme_connection_next = *_conns;
                    207:   conn->tme_connection_type = TME_CONNECTION_BUS_GENERIC;
                    208:   conn->tme_connection_score = tme_bus_device_connection_score;
                    209:   conn->tme_connection_make = tme_bus_device_connection_make;
                    210:   conn->tme_connection_break = tme_bus_device_connection_break;
                    211: 
                    212:   /* fill in the generic bus connection: */
1.1.1.2   root      213:   conn_bus->tme_bus_subregions = device->tme_bus_device_subregions;
1.1       root      214:   if (device->tme_bus_device_signal != NULL) {
                    215:     conn_bus->tme_bus_signal = _tme_bus_device_signal;
                    216:   }
                    217:   if (device->tme_bus_device_intack != NULL) {
                    218:     conn_bus->tme_bus_intack = _tme_bus_device_intack;
                    219:   }
                    220:   conn_bus->tme_bus_tlb_fill = _tme_bus_device_tlb_fill;
                    221: 
                    222:   /* return the connection side possibility: */
                    223:   *_conns = conn;
                    224:   return (TME_OK);
                    225: }

unix.superglobalmegacorp.com

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