1 /* $Id: bus.h,v 1.15 2009/08/29 17:35:08 fredette Exp $ */
2 
3 /* tme/generic/bus.h - header file for generic bus support: */
4 
5 /*
6  * Copyright (c) 2002, 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 #ifndef _TME_GENERIC_BUS_H
37 #define _TME_GENERIC_BUS_H
38 
39 #include <tme/common.h>
40 _TME_RCSID("$Id: bus.h,v 1.15 2009/08/29 17:35:08 fredette Exp $");
41 
42 /* includes: */
43 #include <tme/element.h>
44 #include <tme/threads.h>
45 #include <tme/memory.h>
46 #include <tme/token.h>
47 
48 /* macros: */
49 
50 /* the log2 of various bus sizes, named by number of bits but really
51    in terms of bytes: */
52 #define TME_BUS8_LOG2		(0)
53 #define TME_BUS16_LOG2		(1)
54 #define TME_BUS32_LOG2		(2)
55 #define TME_BUS64_LOG2		(3)
56 #define TME_BUS128_LOG2		(4)
57 
58 /* bus signal flags and form: */
59 #define TME_BUS_SIGNAL_LEVEL_MASK	(0x03)
60 #define  TME_BUS_SIGNAL_LEVEL_LOW	(0x00)
61 #define  TME_BUS_SIGNAL_LEVEL_HIGH	(0x01)
62 #define  TME_BUS_SIGNAL_LEVEL_NEGATED	(0x02)
63 #define  TME_BUS_SIGNAL_LEVEL_ASSERTED	(0x03)
64 #define TME_BUS_SIGNAL_EDGE		(0x04)
65 #define _TME_BUS_SIGNAL_BITS		(5)
66 #define TME_BUS_SIGNAL_WHICH(x)		((x) & ~((1 << _TME_BUS_SIGNAL_BITS) - 1))
67 #define TME_BUS_SIGNAL_INDEX(x)		((x) >> _TME_BUS_SIGNAL_BITS)
68 #define TME_BUS_SIGNAL_X(x)		((x) << _TME_BUS_SIGNAL_BITS)
69 
70 /* all bus signal set identifiers: */
71 #define TME_BUS_SIGNALS_ID_GENERIC	(0)
72 #define TME_BUS_SIGNALS_ID_I825X6	(1)
73 
74 /* the generic bus signal set: */
75 #define TME_BUS_SIGNAL_INT(x)		TME_BUS_SIGNAL_X(x)
76 #define TME_BUS_SIGNAL_IS_INT(x)	(TME_BUS_SIGNAL_INDEX(x) < 256)
77 #define TME_BUS_SIGNAL_INDEX_INT(x)	TME_BUS_SIGNAL_INDEX(x)
78 #define TME_BUS_SIGNAL_INT_UNSPEC	TME_BUS_SIGNAL_X(256)
79 #define TME_BUS_SIGNAL_HALT		TME_BUS_SIGNAL_X(257)
80 #define TME_BUS_SIGNAL_RESET		TME_BUS_SIGNAL_X(258)
81 #define TME_BUS_SIGNAL_IGNORE		TME_BUS_SIGNAL_X(259)
82 #define TME_BUS_SIGNAL_ABORT		TME_BUS_SIGNAL_X(260)
83 #define TME_BUS_SIGNAL_DRQ		TME_BUS_SIGNAL_X(261)
84 #define TME_BUS_SIGNAL_DACK		TME_BUS_SIGNAL_X(262)
85 #define TME_BUS_SIGNAL_BR		TME_BUS_SIGNAL_X(263)
86 #define TME_BUS_SIGNAL_BG		TME_BUS_SIGNAL_X(264)
87 #define TME_BUS_SIGNALS_GENERIC		{ TME_BUS_SIGNALS_ID_GENERIC, TME_BUS_VERSION, 384, 0 }
88 
89 /* this gets the index and mask of a bus signal bit in a byte array: */
90 #define TME_BUS_SIGNAL_BIT_INDEX(x)	(TME_BUS_SIGNAL_INDEX(x) >> 3)
91 #define TME_BUS_SIGNAL_BIT_MASK(x)	TME_BIT(TME_BUS_SIGNAL_INDEX(x) & 7)
92 
93 /* this gets the number of bytes in a byte array of bus signal bits: */
94 #define TME_BUS_SIGNAL_BIT_BYTES(count)	(((count) + 7) >> 3)
95 
96 /* the undefined interrupt vector: */
97 #define TME_BUS_INTERRUPT_VECTOR_UNDEF	(-1)
98 
99 /* bus cycles: */
100 #define TME_BUS_CYCLE_UNDEF	(0)
101 #define TME_BUS_CYCLE_READ	TME_BIT(0)
102 #define TME_BUS_CYCLE_WRITE	TME_BIT(1)
103 #define TME_BUS_CYCLE_LOCK	TME_BIT(2)
104 #define TME_BUS_CYCLE_UNLOCK	TME_BIT(3)
105 
106 /* the maximum number of fault handlers on a TLB entry: */
107 #define TME_BUS_TLB_FAULT_HANDLERS	(4)
108 
109 /* this returns nonzero if a TLB entry is valid: */
110 #define tme_bus_tlb_is_valid(tlb)					\
111   (tme_token_is_valid((tlb)->tme_bus_tlb_token))
112 
113 /* this returns nonzero if a TLB entry is invalid: */
114 #define tme_bus_tlb_is_invalid(tlb)					\
115   (tme_token_is_invalid((tlb)->tme_bus_tlb_token))
116 
117 /* this busies a TLB entry: */
118 #define tme_bus_tlb_busy(tlb)		tme_token_busy((tlb)->tme_bus_tlb_token)
119 
120 /* this unbusies a TLB entry: */
121 #define tme_bus_tlb_unbusy(tlb)		tme_token_unbusy((tlb)->tme_bus_tlb_token)
122 
123 /* this unbusies a TLB entry for filling: */
124 /* NB: we must clear the invalid on the TLB's token before we fill it.
125    we can't do that after we fill it, because we will race with an
126    immediate invalidation.  however, by marking it valid before we fill
127    it, we race with ourselves - before the TLB entry is filled, we may
128    run again and see a TLB entry that was actually invalidated, as
129    valid.  to avoid this case, we invalidate the TLB entry in another
130    way - we poison its first and last addresses to impossible values: */
131 /* NB: once all element callins have been rearchitected to block until
132    a callout has completed, this poisoning can go away: */
133 #define tme_bus_tlb_unbusy_fill(tlb)					\
134   do {									\
135     tme_bus_tlb_unbusy(tlb);						\
136     if (tme_bus_tlb_is_invalid(tlb)) {					\
137       (tlb)->tme_bus_tlb_addr_first = 1;				\
138       (tlb)->tme_bus_tlb_addr_last = 0;					\
139       tme_token_invalid_clear((tlb)->tme_bus_tlb_token);		\
140     }									\
141   } while (/* CONSTCOND */ 0)
142 
143 /* this adds a fault handler to a TLB entry: */
144 #define TME_BUS_TLB_FAULT_HANDLER(tlb, func, private)	\
145 do {							\
146   assert(tlb->tme_bus_tlb_fault_handler_count		\
147 	 < TME_BUS_TLB_FAULT_HANDLERS);			\
148   tlb->tme_bus_tlb_fault_handlers			\
149     [tlb->tme_bus_tlb_fault_handler_count]		\
150     .tme_bus_tlb_fault_handler_private = private;	\
151   tlb->tme_bus_tlb_fault_handlers			\
152     [tlb->tme_bus_tlb_fault_handler_count]		\
153     .tme_bus_tlb_fault_handler = func;			\
154   tlb->tme_bus_tlb_fault_handler_count++;		\
155 } while (/* CONSTCOND */ 0)
156 
157 /* this indexes a generic bus router array for a device with a port
158    size of 8 * (2 ^ siz_lg2) bits: */
159 #define TME_BUS_ROUTER_INDEX(siz_lg2, other_port_siz_lg2, other_port_lane_least) \
160 (((							\
161    /* by the (overlapping) other port size: */		\
162    (other_port_siz_lg2)					\
163 							\
164    /* by the (overlapping) other port least lane: */	\
165     << (siz_lg2))					\
166    + other_port_lane_least)				\
167 							\
168   /* by lane number, which we add later: */		\
169   << (siz_lg2))
170 
171 /* this gives the number of entries that must be in a generic bus
172    router array for a device with a bus size of 8 * (2 ^ siz_lg2)
173    bits: */
174 #define TME_BUS_ROUTER_SIZE(siz_lg2)				\
175   TME_BUS_ROUTER_INDEX(siz_lg2, (siz_lg2) + 1, 0)
176 
177 /* bus lane routing entries: */
178 #define TME_BUS_LANE_WARN			TME_BIT(7)
179 #define TME_BUS_LANE_ABORT			(0x7f)
180 #define TME_BUS_LANE_UNDEF			(0x7e)
181 #define TME_BUS_LANE_ROUTE_WRITE_IGNORE		TME_BIT(6)
182 #define TME_BUS_LANE_ROUTE(x)			(x)
183 
184 /* this is a special bus cycle return value.  it doesn't indicate a
185    fault, but instead tells the initiator that some other event has
186    happened on the bus, synchronous with the bus cycle, that the
187    initiator should handle: */
188 #define TME_BUS_CYCLE_SYNCHRONOUS_EVENT		(EINTR)
189 
190 /* internal bus connection types: */
191 #define TME_BUS_CONNECTION_INT_FLAG_ADDRESSABLE		TME_BIT(0)
192 #define TME_BUS_CONNECTION_INT_FLAG_CONTROLLER		TME_BIT(1)
193 
194 /* types: */
195 struct tme_bus_tlb;
196 
197 /* a bus address: */
198 typedef tme_uint32_t		tme_bus_addr32_t;
199 #ifdef TME_HAVE_INT64_T
200 typedef tme_uint64_t		tme_bus_addr64_t;
201 #endif /* TME_HAVE_INT64_T */
202 #if TME_BUSMAX_LOG2 <= TME_BUS32_LOG2
203 typedef tme_bus_addr32_t	tme_bus_addr_t;
204 #elif TME_BUSMAX_LOG2 == TME_BUS64_LOG2
205 #ifndef TME_HAVE_INT64_T
206 #error "64-bit guests require 64-bit integer types"
207 #else  /* TME_HAVE_INT64_T */
208 typedef tme_bus_addr64_t	tme_bus_addr_t;
209 #endif /* TME_HAVE_INT64_T */
210 #else  /* TME_BUSMAX_LOG2 */
211 #error "unsupported maximum guest bus size"
212 #endif /* TME_BUSMAX_LOG2 */
213 
214 /* a bus byte lane routing entry: */
215 typedef tme_uint8_t		tme_bus_lane_t;
216 
217 /* a bus context: */
218 typedef tme_uint32_t		tme_bus_context_t;
219 
220 /* a bus cycle: */
221 struct tme_bus_cycle {
222 
223   /* the bus cycle data buffer pointer.  this points to the byte
224      associated with the bus address given below: */
225   tme_uint8_t *tme_bus_cycle_buffer;
226 
227   /* how bus byte lanes are connected to the bus cycle data buffer: */
228   _tme_const tme_bus_lane_t *tme_bus_cycle_lane_routing;
229 
230   /* the bus address: */
231   tme_bus_addr_t tme_bus_cycle_address;
232 
233   /* when adding one to the bus address, add this to the bus cycle
234      data buffer pointer to get a pointer to the byte associated with
235      the new bus address: */
236   tme_int8_t tme_bus_cycle_buffer_increment;
237 
238   /* the type of bus cycle: */
239   tme_uint8_t tme_bus_cycle_type;
240 
241   /* the maximum number of addresses that could be covered by this
242      cycle.  depending on where and how wide the initiator and
243      responder ports overlap, the number of addresses actually covered
244      may be less: */
245   tme_uint8_t tme_bus_cycle_size;
246 
247   /* the starting lane and size of this device's port.  bits 0-2 are
248      the log2 of the lane size of the port.  zero corresponds to a
249      one-lane (8-bit) port, one to a two-lane (16-bit) port, etc.
250      bits 3-7 are the least byte lane in this device's port.  zero
251      corresponds to D7-D0, one to D15-D8, etc.: */
252   tme_uint8_t tme_bus_cycle_port;
253 #define TME_BUS_CYCLE_PORT(lane_least, lane_size_lg2) \
254   (((lane_least) << 3) | (lane_size_lg2))
255 #define TME_BUS_CYCLE_PORT_SIZE_LG2(port) \
256   TME_FIELD_EXTRACTU(port, 0, 3)
257 #define TME_BUS_CYCLE_PORT_LANE_LEAST(port) \
258   TME_FIELD_EXTRACTU(port, 3, 5)
259 };
260 
261 /* a bus cycle handler: */
262 typedef int (*tme_bus_cycle_handler) _TME_P((void *, struct tme_bus_cycle *));
263 
264 /* a bus fault handler: */
265 typedef int (*tme_bus_fault_handler) _TME_P((void *, struct tme_bus_tlb *, struct tme_bus_cycle *, int));
266 
267 /* a bus cacheable: */
268 struct tme_bus_cacheable {
269 
270   /* the cacheable contents and size: */
271   tme_shared tme_uint8_t *tme_bus_cacheable_contents;
272   unsigned long tme_bus_cacheable_size;
273 
274   /* the cacheable private state: */
275   void *tme_bus_cacheable_private;
276 
277   /* this function allocates a new valids bitmask: */
278   tme_shared tme_uint8_t *(*tme_bus_cacheable_valids_new) _TME_P((void *, tme_uint32_t));
279 
280   /* this function sets a bit in the valids bitmask: */
281   void (*tme_bus_cacheable_valids_set) _TME_P((void *, tme_shared tme_uint8_t *, unsigned long));
282 };
283 
284 /* a bus TLB entry: */
285 struct tme_bus_tlb {
286 
287   /* the bus address region covered by this TLB entry: */
288   tme_bus_addr_t tme_bus_tlb_addr_first;
289   tme_bus_addr_t tme_bus_tlb_addr_last;
290 
291   /* the token associated with this TLB entry: */
292   struct tme_token *tme_bus_tlb_token;
293 
294   /* when one or both of these pointers are not TME_EMULATOR_OFF_UNDEF,
295      this TLB entry allows fast (memory) reads of and/or writes to the
296      bus region.  adding an address in the bus region to one of these
297      pointers yields the desired host memory address: */
298   _tme_const tme_shared tme_uint8_t *tme_bus_tlb_emulator_off_read;
299   tme_shared tme_uint8_t *tme_bus_tlb_emulator_off_write;
300 
301   /* fast (memory) reads and writes are protected by this rwlock: */
302   tme_rwlock_t *tme_bus_tlb_rwlock;
303 
304   /* if non-NULL, this bus region is cacheable memory: */
305   _tme_const struct tme_bus_cacheable *tme_bus_tlb_cacheable;
306 
307   /* when one or both of TLB_BUS_CYCLE_READ and TLB_BUS_CYCLE_WRITE
308      are set in this value, this TLB entry allows slow (function call)
309      reads of and/or writes to the bus region: */
310   unsigned int tme_bus_tlb_cycles_ok;
311 
312   /* adding an address in the bus region to this offset, and then
313      shifting that result to the right (shift > 0) or to the left
314      (shift < 0) yields an address for the bus cycle handler: */
315   tme_bus_addr_t tme_bus_tlb_addr_offset;
316   int tme_bus_tlb_addr_shift;
317 
318   /* the bus cycle handler: */
319   void *tme_bus_tlb_cycle_private;
320   tme_bus_cycle_handler tme_bus_tlb_cycle;
321 
322   /* the bus fault handlers: */
323   unsigned int tme_bus_tlb_fault_handler_count;
324   struct {
325     void *tme_bus_tlb_fault_handler_private;
326     tme_bus_fault_handler tme_bus_tlb_fault_handler;
327   } tme_bus_tlb_fault_handlers[TME_BUS_TLB_FAULT_HANDLERS];
328 };
329 
330 /* a bus signals set: */
331 struct tme_bus_signals {
332 
333   /* the bus signals set identifier: */
334   tme_uint32_t tme_bus_signals_id;
335 
336   /* the version of the bus signals: */
337   tme_uint32_t tme_bus_signals_version;
338 
339   /* the maximum number of bus signals in the set: */
340   tme_uint32_t tme_bus_signals_count;
341 
342   /* the first signal in the bus signals set: */
343   tme_uint32_t tme_bus_signals_first;
344 };
345 
346 /* a bus master's TLB set information: */
347 struct tme_bus_tlb_set_info {
348 
349   /* the first token in the set: */
350   struct tme_token *tme_bus_tlb_set_info_token0;
351 
352   /* the stride between tokens in the set, in bytes: */
353   unsigned long tme_bus_tlb_set_info_token_stride;
354 
355   /* the count of tokens in the set: */
356   unsigned long tme_bus_tlb_set_info_token_count;
357 
358   /* the set's optional bus context register: */
359   /* NB: this isn't tme_shared because the bus context, when it does
360      exist, is only exposed to the one bus master that can actually
361      change it - and we assume that changing the bus context
362      synchronizes the master: */
363   tme_bus_context_t *tme_bus_tlb_set_info_bus_context;
364 
365   /* the maximum value of the bus context register: */
366   tme_bus_context_t tme_bus_tlb_set_info_bus_context_max;
367 };
368 
369 /* a bus connection: */
370 struct tme_bus_connection {
371 
372   /* the generic connection side: */
373   struct tme_connection tme_bus_connection;
374 
375   /* the subregions on the bus for this connection.  most connections
376      will only have one subregion, with a first address of zero and a
377      last address of their size on the bus: */
378   struct tme_bus_subregion {
379 
380     /* the first and last addresses, starting from zero, of this
381        subregion: */
382     tme_bus_addr_t tme_bus_subregion_address_first;
383     tme_bus_addr_t tme_bus_subregion_address_last;
384 
385     /* any other subregions for this bus connection: */
386     _tme_const struct tme_bus_subregion *tme_bus_subregion_next;
387   } tme_bus_subregions;
388 
389   /* the bus signal set adder: */
390   int (*tme_bus_signals_add) _TME_P((struct tme_bus_connection *,
391 				     struct tme_bus_signals *));
392 
393   /* the bus signal handler: */
394   int (*tme_bus_signal) _TME_P((struct tme_bus_connection *, unsigned int));
395 
396   /* the bus interrupt acknowledge handler: */
397   int (*tme_bus_intack) _TME_P((struct tme_bus_connection *, unsigned int, int *));
398 
399   /* the bus TLB set add handler: */
400   int (*tme_bus_tlb_set_add) _TME_P((struct tme_bus_connection *, struct tme_bus_tlb_set_info *));
401 
402   /* the bus TLB entry filler: */
403   int (*tme_bus_tlb_fill) _TME_P((struct tme_bus_connection *, struct tme_bus_tlb *,
404 				  tme_bus_addr_t, unsigned int));
405 };
406 
407 /* internal information about a bus connection: */
408 struct tme_bus_connection_int {
409 
410   /* the external bus connection: */
411   struct tme_bus_connection tme_bus_connection_int;
412 
413   /* flags on the bus connection: */
414   int tme_bus_connection_int_flags;
415 
416   /* the first and last addresses of this connection.  most code
417      should never use the last-address value, and instead should honor
418      the connection's subregions: */
419   tme_bus_addr_t tme_bus_connection_int_address;
420   tme_bus_addr_t tme_bus_connection_int_address_last;
421 
422   /* the mask added to addresses sourced by this connection: */
423   tme_bus_addr_t tme_bus_connection_int_sourced;
424 
425   /* the single interrupt signal used by this connection, when
426      the connection doesn't know already: */
427   int tme_bus_connection_int_signal_int;
428 
429   /* the single interrupt vector used by this connection, when the
430      connection doesn't know already: */
431   int tme_bus_connection_int_vector_int;
432 
433   /* nonzero iff we've already logged an unconfigured interrupt
434      signal: */
435   int tme_bus_connection_int_logged_int;
436 
437   /* the current status of the bus signals for this connection: */
438   tme_uint8_t *tme_bus_connection_int_signals;
439 };
440 
441 /* a generic bus slot: */
442 struct tme_bus_slot {
443 
444   /* generic bus slots are kept on a list: */
445   struct tme_bus_slot *tme_bus_slot_next;
446 
447   /* the name of this bus slot: */
448   char *tme_bus_slot_name;
449 
450   /* the address and size of this bus slot: */
451   tme_bus_addr_t tme_bus_slot_address;
452   tme_bus_addr_t tme_bus_slot_size;
453 };
454 
455 /* a generic bus: */
456 struct tme_bus {
457 
458   /* the optional rwlock protecting this bus: */
459   tme_rwlock_t tme_bus_rwlock;
460 
461   /* the address mask used on this bus: */
462   tme_bus_addr_t tme_bus_address_mask;
463 
464   /* all connections to this bus: */
465   struct tme_bus_connection_int *tme_bus_connections;
466 
467   /* the number of addressable connections to this bus: */
468   int tme_bus_addressables_count;
469 
470   /* the size of the addressable connections array: */
471   int tme_bus_addressables_size;
472 
473   /* the addressable connections array: */
474   struct tme_bus_addressable {
475     struct tme_bus_connection_int *tme_bus_addressable_connection;
476     _tme_const struct tme_bus_subregion *tme_bus_addressable_subregion;
477   } *tme_bus_addressables;
478 
479   /* the bus signal sets on this bus: */
480   unsigned int tme_bus_signals_count;
481   struct tme_bus_signals *tme_bus_signals;
482 
483   /* the number of devices asserting the various bus signals: */
484   unsigned int *tme_bus_signal_asserts;
485 
486   /* any bus slots: */
487   struct tme_bus_slot *tme_bus_slots;
488 
489   /* any bus controller connection: */
490   struct tme_bus_connection_int *tme_bus_controller;
491 };
492 
493 /* prototypes: */
494 int tme_bus_address_search _TME_P((struct tme_bus *, tme_bus_addr_t));
495 int tme_bus_connection_ok _TME_P((struct tme_bus *,
496 				  struct tme_bus_connection_int *));
497 int tme_bus_connection_make _TME_P((struct tme_bus *,
498 				    struct tme_bus_connection_int *,
499 				    unsigned int));
500 int tme_bus_connection_break _TME_P((struct tme_bus *,
501 				     struct tme_bus_connection_int *,
502 				     unsigned int));
503 int tme_bus_tlb_fill _TME_P((struct tme_bus *,
504 			     struct tme_bus_connection_int *,
505 			     struct tme_bus_tlb *, tme_bus_addr_t, unsigned int));
506 int tme_bus_tlb_set_add _TME_P((struct tme_bus *,
507 				struct tme_bus_connection_int *,
508 				struct tme_bus_tlb_set_info *));
509 void tme_bus_tlb_set_invalidate _TME_P((_tme_const struct tme_bus_tlb_set_info *));
510 void tme_bus_tlb_map _TME_P((struct tme_bus_tlb *, tme_bus_addr_t, _tme_const struct tme_bus_tlb *, tme_bus_addr_t));
511 void tme_bus_tlb_initialize _TME_P((struct tme_bus_tlb *));
512 int tme_bus_tlb_fault _TME_P((struct tme_bus_tlb *, struct tme_bus_cycle *, int));
513 tme_bus_addr_t tme_bus_addr_parse _TME_P((_tme_const char *, tme_bus_addr_t));
514 tme_bus_addr_t tme_bus_addr_parse_any _TME_P((_tme_const char *, int *));
515 void tme_bus_cycle_xfer _TME_P((struct tme_bus_cycle *, struct tme_bus_cycle *));
516 void tme_bus_cycle_xfer_memory _TME_P((struct tme_bus_cycle *, tme_uint8_t *, tme_bus_addr_t));
517 void tme_bus_cycle_xfer_reg _TME_P((struct tme_bus_cycle *, void *, unsigned int));
518 
519 #endif /* !_TME_GENERIC_BUS_H */
520