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 */ 242