|
|
1.1 ! root 1: /* $Id: stp22xx-impl.h,v 1.2 2009/08/29 21:17:06 fredette Exp $ */ ! 2: ! 3: /* ic/stp22xx/stp22xx-impl.h - implementation header file for STP2200, ! 4: STP2202, STP2220, and STP2222 emulation: */ ! 5: ! 6: /* ! 7: * Copyright (c) 2009 Matt Fredette ! 8: * All rights reserved. ! 9: * ! 10: * Redistribution and use in source and binary forms, with or without ! 11: * modification, are permitted provided that the following conditions ! 12: * are met: ! 13: * 1. Redistributions of source code must retain the above copyright ! 14: * notice, this list of conditions and the following disclaimer. ! 15: * 2. Redistributions in binary form must reproduce the above copyright ! 16: * notice, this list of conditions and the following disclaimer in the ! 17: * documentation and/or other materials provided with the distribution. ! 18: * 3. All advertising materials mentioning features or use of this software ! 19: * must display the following acknowledgement: ! 20: * This product includes software developed by Matt Fredette. ! 21: * 4. The name of the author may not be used to endorse or promote products ! 22: * derived from this software without specific prior written permission. ! 23: * ! 24: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ! 25: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ! 26: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ! 27: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ! 28: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ! 29: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ! 30: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ! 32: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ! 33: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! 34: * POSSIBILITY OF SUCH DAMAGE. ! 35: */ ! 36: ! 37: #ifndef _STP22XX_IMPL_H ! 38: #define _STP22XX_IMPL_H ! 39: ! 40: #include <tme/common.h> ! 41: _TME_RCSID("$Id: stp22xx-impl.h,v 1.2 2009/08/29 21:17:06 fredette Exp $"); ! 42: ! 43: /* includes: */ ! 44: #include <tme/completion.h> ! 45: #include <tme/bus/upa.h> ! 46: ! 47: /* macros: */ ! 48: ! 49: /* this macro wraps code used during the transition to the new bus ! 50: interface. the new bus interface will remove everything from ! 51: struct tme_bus_tlb starting with the tme_bus_tlb_cycles_ok member ! 52: until the end. this will remove all slow cycle information from a ! 53: TLB, so TLB filling will only give fast read and write information. ! 54: ! 55: every bus connection will then have a slow cycle function. when a ! 56: master needs to do a slow cycle, through its bus connection it will ! 57: arbitrate for the bus and then start its cycle. the bus ! 58: implementation will steer the cycle towards the slave, which may be ! 59: across a bridge and over another bus, etc. slow bus cycles will ! 60: then follow the actual path from master to slave, with bus ! 61: implementations ordering bus access and cycles as needed. ! 62: ! 63: this seems better than the old interface, where masters called ! 64: directly into slaves through function pointers in a TLB. in the ! 65: old interface, buses couldn't enforce any ordering, because they ! 66: weren't involved. this created the risk that a master in the ! 67: middle of running a bus cycle could be called as a slave over the ! 68: same bus connection. real devices never have to face that, and ! 69: without eliminating that here, turning on preemptive threading ! 70: seems impossible. ! 71: ! 72: the new cycle function in a bus connection will take the bus ! 73: connection, the struct tme_bus_cycle *, a struct tme_completion *, ! 74: and a pointer to a mask of cycle types that can be done fast. as ! 75: the slow bus cycle makes its way from master to slave, if any point ! 76: along that path can't allow fast reads or writes, those bits are ! 77: cleared from the mask. when the slow cycle completes, if the ! 78: master finds that any cycles can be done fast again, it may choose ! 79: to fill a TLB entry again to get the new fast cycle information. ! 80: this frees slaves from having to track filled TLBs that weren't ! 81: filled with any fast cycle information, just so they can be ! 82: invalidated when addresses become fast-capable to make sure that ! 83: masters refill them. ! 84: ! 85: eventually, all of the code wrapped by this macro will be ! 86: removed: */ ! 87: #define TME_STP22XX_BUS_TRANSITION (TRUE) ! 88: ! 89: /* the maximum number of completions: */ ! 90: #define TME_STP22XX_COMPLETIONS_MAX (2) ! 91: ! 92: /* the maximum number of delayed completions: */ ! 93: #define TME_STP22XX_COMPLETIONS_DELAYED_MAX (2) ! 94: ! 95: /* condition states: */ ! 96: #define TME_STP22XX_COND_STATE_IDLE (0) ! 97: #define TME_STP22XX_COND_STATE_RUNNING (1) ! 98: #define TME_STP22XX_COND_STATE_WAITING (2) ! 99: #define TME_STP22XX_COND_STATE_NOTIFIED (3) ! 100: ! 101: /* types: */ ! 102: struct tme_stp22xx; ! 103: ! 104: /* a completion handler: */ ! 105: typedef void (*_tme_stp22xx_completion_handler_t) _TME_P((struct tme_stp22xx *, struct tme_completion *, void *)); ! 106: ! 107: /* a condition: */ ! 108: struct tme_stp22xx_cond { ! 109: int tme_stp22xx_cond_state; ! 110: tme_cond_t tme_stp22xx_cond_cond; ! 111: }; ! 112: ! 113: /* a connection: */ ! 114: union tme_stp22xx_conn { ! 115: struct tme_bus_connection *tme_stp22xx_conn_bus; ! 116: struct tme_upa_bus_connection *tme_stp22xx_conn_upa; ! 117: }; ! 118: ! 119: /* the device: */ ! 120: struct tme_stp22xx { ! 121: ! 122: /* backpointer to the device's element: */ ! 123: struct tme_element *tme_stp22xx_element; ! 124: ! 125: /* the mutex protecting the device: */ ! 126: tme_mutex_t tme_stp22xx_mutex; ! 127: ! 128: /* the size of the part-specific structure: */ ! 129: unsigned long tme_stp22xx_sizeof; ! 130: ! 131: /* this is nonzero if the run function is running: */ ! 132: int tme_stp22xx_running; ! 133: ! 134: /* the run function: */ ! 135: void (*tme_stp22xx_run) _TME_P((struct tme_stp22xx *)); ! 136: ! 137: /* our completions: */ ! 138: struct tme_completion tme_stp22xx_completions[TME_STP22XX_COMPLETIONS_MAX]; ! 139: _tme_stp22xx_completion_handler_t tme_stp22xx_completion_handlers[TME_STP22XX_COMPLETIONS_MAX]; ! 140: void * tme_stp22xx_completion_args[TME_STP22XX_COMPLETIONS_MAX]; ! 141: ! 142: /* any delayed completions: */ ! 143: /* NB: this array is always NULL-terminated: */ ! 144: struct tme_completion *tme_stp22xx_completions_delayed[TME_STP22XX_COMPLETIONS_DELAYED_MAX + 1]; ! 145: ! 146: /* the undefined connection index: */ ! 147: tme_uint32_t tme_stp22xx_conn_index_null; ! 148: ! 149: /* any pending master connection index: */ ! 150: tme_uint32_t tme_stp22xx_master_conn_index_pending; ! 151: ! 152: /* any current master connection index and its completion: */ ! 153: tme_uint32_t tme_stp22xx_master_conn_index; ! 154: struct tme_completion **tme_stp22xx_master_completion; ! 155: ! 156: #if TME_STP22XX_BUS_TRANSITION ! 157: /* the token for filling TLB entries for slave cycles: */ ! 158: struct tme_token tme_stp22xx_slave_cycle_tlb_token; ! 159: #endif /* TME_STP22XX_BUS_TRANSITION */ ! 160: ! 161: /* any current slave connection: */ ! 162: struct tme_bus_connection *tme_stp22xx_slave_conn_bus; ! 163: ! 164: /* the connections: */ ! 165: /* NB: this must be the last member of this structure; the ! 166: part-specific structure allocates enough space for its real ! 167: size: */ ! 168: union tme_stp22xx_conn tme_stp22xx_conns[1]; ! 169: }; ! 170: ! 171: /* prototypes: */ ! 172: ! 173: /* this busies a generic bus connection: */ ! 174: struct tme_bus_connection *tme_stp22xx_busy_bus _TME_P((struct tme_stp22xx *, tme_uint32_t)); ! 175: ! 176: /* this unbusies a generic bus connection: */ ! 177: void tme_stp22xx_unbusy_bus _TME_P((struct tme_stp22xx *, struct tme_bus_connection *)); ! 178: ! 179: /* this busies a slave generic bus connection: */ ! 180: struct tme_bus_connection *tme_stp22xx_slave_busy_bus _TME_P((struct tme_stp22xx *, tme_uint32_t)); ! 181: ! 182: /* this unbusies a slave generic bus connection: */ ! 183: void tme_stp22xx_slave_unbusy _TME_P((struct tme_stp22xx *)); ! 184: ! 185: /* this enters: */ ! 186: struct tme_stp22xx *tme_stp22xx_enter _TME_P((struct tme_stp22xx *)); ! 187: ! 188: /* this enters as the bus master: */ ! 189: struct tme_stp22xx *tme_stp22xx_enter_master _TME_P((struct tme_bus_connection *)); ! 190: ! 191: /* this leaves: */ ! 192: void tme_stp22xx_leave _TME_P((struct tme_stp22xx *)); ! 193: ! 194: /* this waits on a condition, with an optional sleep time: */ ! 195: void tme_stp22xx_cond_sleep_yield _TME_P((struct tme_stp22xx *, struct tme_stp22xx_cond *, const struct timeval *)); ! 196: ! 197: /* this validates a completion: */ ! 198: void tme_stp22xx_completion_validate _TME_P((struct tme_stp22xx *, struct tme_completion *)); ! 199: ! 200: /* this allocates a completion: */ ! 201: struct tme_completion *tme_stp22xx_completion_alloc _TME_P((struct tme_stp22xx *, _tme_stp22xx_completion_handler_t, void *)); ! 202: ! 203: /* this calls out a bus signal to a connection: */ ! 204: void tme_stp22xx_callout_signal _TME_P((struct tme_stp22xx *, tme_uint32_t, unsigned int, _tme_stp22xx_completion_handler_t)); ! 205: ! 206: /* this completes a bus grant: */ ! 207: void tme_stp22xx_complete_bg _TME_P((struct tme_stp22xx *, struct tme_completion *, void *)); ! 208: ! 209: /* this completes a bus operation between master and slave: */ ! 210: void tme_stp22xx_complete_master _TME_P((struct tme_stp22xx *, struct tme_completion *, void *)); ! 211: ! 212: /* this is a no-op completion: */ ! 213: void tme_stp22xx_complete_nop _TME_P((struct tme_stp22xx *, struct tme_completion *, void *)); ! 214: ! 215: /* this runs a slave bus cycle: */ ! 216: void tme_stp22xx_slave_cycle _TME_P((struct tme_bus_connection *, tme_uint32_t, struct tme_bus_cycle *, tme_uint32_t *, struct tme_completion **)); ! 217: ! 218: /* this fills a TLB entry: */ ! 219: void tme_stp22xx_tlb_fill _TME_P((struct tme_bus_connection *, struct tme_bus_tlb *, tme_uint32_t, tme_bus_addr64_t, unsigned int)); ! 220: ! 221: /* this adds a TLB set: */ ! 222: void tme_stp22xx_tlb_set_add _TME_P((struct tme_bus_connection *, struct tme_bus_tlb_set_info *, struct tme_completion *)); ! 223: ! 224: #if TME_STP22XX_BUS_TRANSITION ! 225: ! 226: /* this is the bus TLB set add transition glue: */ ! 227: int tme_stp22xx_tlb_set_add_transition _TME_P((struct tme_bus_connection *, struct tme_bus_tlb_set_info *)); ! 228: #define tme_stp22xx_tlb_set_add tme_stp22xx_tlb_set_add_transition ! 229: ! 230: #endif /* TME_STP22XX_BUS_TRANSITION */ ! 231: ! 232: /* this notifies a condition: */ ! 233: void tme_stp22xx_cond_notify _TME_P((struct tme_stp22xx_cond *)); ! 234: ! 235: /* this initializes a condition: */ ! 236: void tme_stp22xx_cond_init _TME_P((struct tme_stp22xx_cond *)); ! 237: ! 238: /* this initializes an stp22xx: */ ! 239: void tme_stp22xx_init _TME_P((struct tme_stp22xx *, unsigned long, tme_uint32_t)); ! 240: ! 241: #endif /* !_STP22XX_IMPL_H */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.