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

1.1.1.4 ! root        1: /* $Id: bus-device.c,v 1.9 2006/09/30 12:43:35 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.4 ! root       37: _TME_RCSID("$Id: bus-device.c,v 1.9 2006/09/30 12:43:35 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       root       45: /* this scores a connection: */
                     46: int
                     47: tme_bus_device_connection_score(struct tme_connection *conn, unsigned int *_score)
                     48: {
                     49:   struct tme_bus_device *device;
                     50:   struct tme_bus_connection *conn_bus_other_old;
                     51:   struct tme_bus_connection *conn_bus_other_new;
                     52: 
                     53:   /* recover our device: */
                     54:   device = conn->tme_connection_element->tme_element_private;
                     55: 
                     56:   /* both sides must be generic bus connections: */
                     57:   assert(conn->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                     58:   assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                     59: 
                     60:   /* a simple bus device can have multiple connections, but they all
                     61:      must be from the same bus.  the only way we check that is by
                     62:      comparing elements: */
1.1.1.4 ! root       63:   conn_bus_other_old
        !            64:     = tme_memory_atomic_pointer_read(struct tme_bus_connection *,
        !            65:                                     device->tme_bus_device_connection,
        !            66:                                     &device->tme_bus_device_connection_rwlock);
1.1       root       67:   conn_bus_other_new = (struct tme_bus_connection *) conn->tme_connection_other;
                     68:   if (conn_bus_other_old != NULL
                     69:       && (conn_bus_other_old->tme_bus_connection.tme_connection_element
                     70:          != conn_bus_other_new->tme_bus_connection.tme_connection_element)) {
                     71:     *_score = 0;
                     72:     return (TME_OK);
                     73:   }
                     74: 
                     75:   /* otherwise, this is our first connection or another connection to
                     76:      the same element.  note that there's no good way to differentiate
                     77:      a connection to a bus from a connection to just another chip, so
                     78:      we always return a nonzero score here: */
                     79:   *_score = 1;
                     80:   return (TME_OK);
                     81: }
                     82: 
                     83: /* this makes a new connection: */
                     84: int
                     85: tme_bus_device_connection_make(struct tme_connection *conn, unsigned int state)
                     86: {
                     87:   struct tme_bus_device *device;
                     88: 
                     89:   /* recover our device: */
                     90:   device = conn->tme_connection_element->tme_element_private;
                     91: 
                     92:   /* both sides must be generic bus connections: */
                     93:   assert(conn->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                     94:   assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_BUS_GENERIC);
                     95: 
                     96:   /* simple bus devices are always set up to answer calls across the
                     97:      connection, so we only have to do work when the connection
                     98:      has gone full, namely taking the other side of the
                     99:      connection: */
                    100:   if (state == TME_CONNECTION_FULL) {
                    101: 
                    102:     /* save our connection: */
1.1.1.4 ! root      103:     tme_memory_atomic_pointer_write(struct tme_bus_connection *,
        !           104:                                    device->tme_bus_device_connection,
        !           105:                                    (struct tme_bus_connection *) conn->tme_connection_other,
        !           106:                                    &device->tme_bus_device_connection_rwlock);
1.1       root      107:   }
                    108: 
                    109:   return (TME_OK);
                    110: }
                    111: 
                    112: /* this breaks a connection: */
                    113: int
                    114: tme_bus_device_connection_break(struct tme_connection *conn, unsigned int state)
                    115: {
                    116:   abort();
                    117: }
                    118: 
                    119: static int
                    120: _tme_bus_device_signal(struct tme_bus_connection *conn_bus, unsigned int signal)
                    121: {
                    122:   struct tme_bus_device *device;
                    123:   device = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private;
                    124:   return ((*device->tme_bus_device_signal)(device, signal));
                    125: }
                    126: 
                    127: static int
                    128: _tme_bus_device_intack(struct tme_bus_connection *conn_bus, unsigned int signal, int *vector)
                    129: {
                    130:   struct tme_bus_device *device;
                    131:   device = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private;
                    132:   return ((*device->tme_bus_device_intack)(device, signal, vector));
                    133: }
                    134: 
                    135: static int
                    136: _tme_bus_device_tlb_fill(struct tme_bus_connection *conn_bus, struct tme_bus_tlb *tlb,
                    137:                         tme_bus_addr_t address, unsigned int cycles)
                    138: {
                    139:   struct tme_bus_device *device;
                    140:   device = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private;
                    141:   return ((*device->tme_bus_device_tlb_fill)(device, tlb, address, cycles));
                    142: }
                    143: 
                    144: /* this makes a new connection side for a simple bus device: */
                    145: int
                    146: tme_bus_device_connections_new(struct tme_element *element,
                    147:                               const char * const *args,
                    148:                               struct tme_connection **_conns,
                    149:                               char **_output)
                    150: {
                    151:   struct tme_bus_device *device;
                    152:   struct tme_bus_connection *conn_bus;
                    153:   struct tme_connection *conn;
                    154: 
                    155:   /* recover our device: */
                    156:   device = (struct tme_bus_device *) element->tme_element_private;
                    157: 
                    158:   /* create our side of a generic bus connection: */
                    159:   conn_bus = tme_new0(struct tme_bus_connection, 1);
                    160:   conn = &conn_bus->tme_bus_connection;
                    161: 
                    162:   /* fill in the generic connection: */
                    163:   conn->tme_connection_next = *_conns;
                    164:   conn->tme_connection_type = TME_CONNECTION_BUS_GENERIC;
                    165:   conn->tme_connection_score = tme_bus_device_connection_score;
                    166:   conn->tme_connection_make = tme_bus_device_connection_make;
                    167:   conn->tme_connection_break = tme_bus_device_connection_break;
                    168: 
                    169:   /* fill in the generic bus connection: */
1.1.1.2   root      170:   conn_bus->tme_bus_subregions = device->tme_bus_device_subregions;
1.1       root      171:   if (device->tme_bus_device_signal != NULL) {
                    172:     conn_bus->tme_bus_signal = _tme_bus_device_signal;
                    173:   }
                    174:   if (device->tme_bus_device_intack != NULL) {
                    175:     conn_bus->tme_bus_intack = _tme_bus_device_intack;
                    176:   }
                    177:   conn_bus->tme_bus_tlb_fill = _tme_bus_device_tlb_fill;
                    178: 
                    179:   /* return the connection side possibility: */
                    180:   *_conns = conn;
                    181:   return (TME_OK);
                    182: }

unix.superglobalmegacorp.com

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