|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.