|
|
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.