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