mirror of
https://github.com/phabrics/Run-Sun3-SunOS-4.1.1.git
synced 2026-04-29 19:12:58 -04:00
520 lines
19 KiB
C
520 lines
19 KiB
C
/* $Id: bus.h,v 1.15 2009/08/29 17:35:08 fredette Exp $ */
|
|
|
|
/* tme/generic/bus.h - header file for generic bus support: */
|
|
|
|
/*
|
|
* Copyright (c) 2002, 2003 Matt Fredette
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by Matt Fredette.
|
|
* 4. The name of the author may not be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#ifndef _TME_GENERIC_BUS_H
|
|
#define _TME_GENERIC_BUS_H
|
|
|
|
#include <tme/common.h>
|
|
_TME_RCSID("$Id: bus.h,v 1.15 2009/08/29 17:35:08 fredette Exp $");
|
|
|
|
/* includes: */
|
|
#include <tme/element.h>
|
|
#include <tme/threads.h>
|
|
#include <tme/memory.h>
|
|
#include <tme/token.h>
|
|
|
|
/* macros: */
|
|
|
|
/* the log2 of various bus sizes, named by number of bits but really
|
|
in terms of bytes: */
|
|
#define TME_BUS8_LOG2 (0)
|
|
#define TME_BUS16_LOG2 (1)
|
|
#define TME_BUS32_LOG2 (2)
|
|
#define TME_BUS64_LOG2 (3)
|
|
#define TME_BUS128_LOG2 (4)
|
|
|
|
/* bus signal flags and form: */
|
|
#define TME_BUS_SIGNAL_LEVEL_MASK (0x03)
|
|
#define TME_BUS_SIGNAL_LEVEL_LOW (0x00)
|
|
#define TME_BUS_SIGNAL_LEVEL_HIGH (0x01)
|
|
#define TME_BUS_SIGNAL_LEVEL_NEGATED (0x02)
|
|
#define TME_BUS_SIGNAL_LEVEL_ASSERTED (0x03)
|
|
#define TME_BUS_SIGNAL_EDGE (0x04)
|
|
#define _TME_BUS_SIGNAL_BITS (5)
|
|
#define TME_BUS_SIGNAL_WHICH(x) ((x) & ~((1 << _TME_BUS_SIGNAL_BITS) - 1))
|
|
#define TME_BUS_SIGNAL_INDEX(x) ((x) >> _TME_BUS_SIGNAL_BITS)
|
|
#define TME_BUS_SIGNAL_X(x) ((x) << _TME_BUS_SIGNAL_BITS)
|
|
|
|
/* all bus signal set identifiers: */
|
|
#define TME_BUS_SIGNALS_ID_GENERIC (0)
|
|
#define TME_BUS_SIGNALS_ID_I825X6 (1)
|
|
|
|
/* the generic bus signal set: */
|
|
#define TME_BUS_SIGNAL_INT(x) TME_BUS_SIGNAL_X(x)
|
|
#define TME_BUS_SIGNAL_IS_INT(x) (TME_BUS_SIGNAL_INDEX(x) < 256)
|
|
#define TME_BUS_SIGNAL_INDEX_INT(x) TME_BUS_SIGNAL_INDEX(x)
|
|
#define TME_BUS_SIGNAL_INT_UNSPEC TME_BUS_SIGNAL_X(256)
|
|
#define TME_BUS_SIGNAL_HALT TME_BUS_SIGNAL_X(257)
|
|
#define TME_BUS_SIGNAL_RESET TME_BUS_SIGNAL_X(258)
|
|
#define TME_BUS_SIGNAL_IGNORE TME_BUS_SIGNAL_X(259)
|
|
#define TME_BUS_SIGNAL_ABORT TME_BUS_SIGNAL_X(260)
|
|
#define TME_BUS_SIGNAL_DRQ TME_BUS_SIGNAL_X(261)
|
|
#define TME_BUS_SIGNAL_DACK TME_BUS_SIGNAL_X(262)
|
|
#define TME_BUS_SIGNAL_BR TME_BUS_SIGNAL_X(263)
|
|
#define TME_BUS_SIGNAL_BG TME_BUS_SIGNAL_X(264)
|
|
#define TME_BUS_SIGNALS_GENERIC { TME_BUS_SIGNALS_ID_GENERIC, TME_BUS_VERSION, 384, 0 }
|
|
|
|
/* this gets the index and mask of a bus signal bit in a byte array: */
|
|
#define TME_BUS_SIGNAL_BIT_INDEX(x) (TME_BUS_SIGNAL_INDEX(x) >> 3)
|
|
#define TME_BUS_SIGNAL_BIT_MASK(x) TME_BIT(TME_BUS_SIGNAL_INDEX(x) & 7)
|
|
|
|
/* this gets the number of bytes in a byte array of bus signal bits: */
|
|
#define TME_BUS_SIGNAL_BIT_BYTES(count) (((count) + 7) >> 3)
|
|
|
|
/* the undefined interrupt vector: */
|
|
#define TME_BUS_INTERRUPT_VECTOR_UNDEF (-1)
|
|
|
|
/* bus cycles: */
|
|
#define TME_BUS_CYCLE_UNDEF (0)
|
|
#define TME_BUS_CYCLE_READ TME_BIT(0)
|
|
#define TME_BUS_CYCLE_WRITE TME_BIT(1)
|
|
#define TME_BUS_CYCLE_LOCK TME_BIT(2)
|
|
#define TME_BUS_CYCLE_UNLOCK TME_BIT(3)
|
|
|
|
/* the maximum number of fault handlers on a TLB entry: */
|
|
#define TME_BUS_TLB_FAULT_HANDLERS (4)
|
|
|
|
/* this returns nonzero if a TLB entry is valid: */
|
|
#define tme_bus_tlb_is_valid(tlb) \
|
|
(tme_token_is_valid((tlb)->tme_bus_tlb_token))
|
|
|
|
/* this returns nonzero if a TLB entry is invalid: */
|
|
#define tme_bus_tlb_is_invalid(tlb) \
|
|
(tme_token_is_invalid((tlb)->tme_bus_tlb_token))
|
|
|
|
/* this busies a TLB entry: */
|
|
#define tme_bus_tlb_busy(tlb) tme_token_busy((tlb)->tme_bus_tlb_token)
|
|
|
|
/* this unbusies a TLB entry: */
|
|
#define tme_bus_tlb_unbusy(tlb) tme_token_unbusy((tlb)->tme_bus_tlb_token)
|
|
|
|
/* this unbusies a TLB entry for filling: */
|
|
/* NB: we must clear the invalid on the TLB's token before we fill it.
|
|
we can't do that after we fill it, because we will race with an
|
|
immediate invalidation. however, by marking it valid before we fill
|
|
it, we race with ourselves - before the TLB entry is filled, we may
|
|
run again and see a TLB entry that was actually invalidated, as
|
|
valid. to avoid this case, we invalidate the TLB entry in another
|
|
way - we poison its first and last addresses to impossible values: */
|
|
/* NB: once all element callins have been rearchitected to block until
|
|
a callout has completed, this poisoning can go away: */
|
|
#define tme_bus_tlb_unbusy_fill(tlb) \
|
|
do { \
|
|
tme_bus_tlb_unbusy(tlb); \
|
|
if (tme_bus_tlb_is_invalid(tlb)) { \
|
|
(tlb)->tme_bus_tlb_addr_first = 1; \
|
|
(tlb)->tme_bus_tlb_addr_last = 0; \
|
|
tme_token_invalid_clear((tlb)->tme_bus_tlb_token); \
|
|
} \
|
|
} while (/* CONSTCOND */ 0)
|
|
|
|
/* this adds a fault handler to a TLB entry: */
|
|
#define TME_BUS_TLB_FAULT_HANDLER(tlb, func, private) \
|
|
do { \
|
|
assert(tlb->tme_bus_tlb_fault_handler_count \
|
|
< TME_BUS_TLB_FAULT_HANDLERS); \
|
|
tlb->tme_bus_tlb_fault_handlers \
|
|
[tlb->tme_bus_tlb_fault_handler_count] \
|
|
.tme_bus_tlb_fault_handler_private = private; \
|
|
tlb->tme_bus_tlb_fault_handlers \
|
|
[tlb->tme_bus_tlb_fault_handler_count] \
|
|
.tme_bus_tlb_fault_handler = func; \
|
|
tlb->tme_bus_tlb_fault_handler_count++; \
|
|
} while (/* CONSTCOND */ 0)
|
|
|
|
/* this indexes a generic bus router array for a device with a port
|
|
size of 8 * (2 ^ siz_lg2) bits: */
|
|
#define TME_BUS_ROUTER_INDEX(siz_lg2, other_port_siz_lg2, other_port_lane_least) \
|
|
((( \
|
|
/* by the (overlapping) other port size: */ \
|
|
(other_port_siz_lg2) \
|
|
\
|
|
/* by the (overlapping) other port least lane: */ \
|
|
<< (siz_lg2)) \
|
|
+ other_port_lane_least) \
|
|
\
|
|
/* by lane number, which we add later: */ \
|
|
<< (siz_lg2))
|
|
|
|
/* this gives the number of entries that must be in a generic bus
|
|
router array for a device with a bus size of 8 * (2 ^ siz_lg2)
|
|
bits: */
|
|
#define TME_BUS_ROUTER_SIZE(siz_lg2) \
|
|
TME_BUS_ROUTER_INDEX(siz_lg2, (siz_lg2) + 1, 0)
|
|
|
|
/* bus lane routing entries: */
|
|
#define TME_BUS_LANE_WARN TME_BIT(7)
|
|
#define TME_BUS_LANE_ABORT (0x7f)
|
|
#define TME_BUS_LANE_UNDEF (0x7e)
|
|
#define TME_BUS_LANE_ROUTE_WRITE_IGNORE TME_BIT(6)
|
|
#define TME_BUS_LANE_ROUTE(x) (x)
|
|
|
|
/* this is a special bus cycle return value. it doesn't indicate a
|
|
fault, but instead tells the initiator that some other event has
|
|
happened on the bus, synchronous with the bus cycle, that the
|
|
initiator should handle: */
|
|
#define TME_BUS_CYCLE_SYNCHRONOUS_EVENT (EINTR)
|
|
|
|
/* internal bus connection types: */
|
|
#define TME_BUS_CONNECTION_INT_FLAG_ADDRESSABLE TME_BIT(0)
|
|
#define TME_BUS_CONNECTION_INT_FLAG_CONTROLLER TME_BIT(1)
|
|
|
|
/* types: */
|
|
struct tme_bus_tlb;
|
|
|
|
/* a bus address: */
|
|
typedef tme_uint32_t tme_bus_addr32_t;
|
|
#ifdef TME_HAVE_INT64_T
|
|
typedef tme_uint64_t tme_bus_addr64_t;
|
|
#endif /* TME_HAVE_INT64_T */
|
|
#if TME_BUSMAX_LOG2 <= TME_BUS32_LOG2
|
|
typedef tme_bus_addr32_t tme_bus_addr_t;
|
|
#elif TME_BUSMAX_LOG2 == TME_BUS64_LOG2
|
|
#ifndef TME_HAVE_INT64_T
|
|
#error "64-bit guests require 64-bit integer types"
|
|
#else /* TME_HAVE_INT64_T */
|
|
typedef tme_bus_addr64_t tme_bus_addr_t;
|
|
#endif /* TME_HAVE_INT64_T */
|
|
#else /* TME_BUSMAX_LOG2 */
|
|
#error "unsupported maximum guest bus size"
|
|
#endif /* TME_BUSMAX_LOG2 */
|
|
|
|
/* a bus byte lane routing entry: */
|
|
typedef tme_uint8_t tme_bus_lane_t;
|
|
|
|
/* a bus context: */
|
|
typedef tme_uint32_t tme_bus_context_t;
|
|
|
|
/* a bus cycle: */
|
|
struct tme_bus_cycle {
|
|
|
|
/* the bus cycle data buffer pointer. this points to the byte
|
|
associated with the bus address given below: */
|
|
tme_uint8_t *tme_bus_cycle_buffer;
|
|
|
|
/* how bus byte lanes are connected to the bus cycle data buffer: */
|
|
_tme_const tme_bus_lane_t *tme_bus_cycle_lane_routing;
|
|
|
|
/* the bus address: */
|
|
tme_bus_addr_t tme_bus_cycle_address;
|
|
|
|
/* when adding one to the bus address, add this to the bus cycle
|
|
data buffer pointer to get a pointer to the byte associated with
|
|
the new bus address: */
|
|
tme_int8_t tme_bus_cycle_buffer_increment;
|
|
|
|
/* the type of bus cycle: */
|
|
tme_uint8_t tme_bus_cycle_type;
|
|
|
|
/* the maximum number of addresses that could be covered by this
|
|
cycle. depending on where and how wide the initiator and
|
|
responder ports overlap, the number of addresses actually covered
|
|
may be less: */
|
|
tme_uint8_t tme_bus_cycle_size;
|
|
|
|
/* the starting lane and size of this device's port. bits 0-2 are
|
|
the log2 of the lane size of the port. zero corresponds to a
|
|
one-lane (8-bit) port, one to a two-lane (16-bit) port, etc.
|
|
bits 3-7 are the least byte lane in this device's port. zero
|
|
corresponds to D7-D0, one to D15-D8, etc.: */
|
|
tme_uint8_t tme_bus_cycle_port;
|
|
#define TME_BUS_CYCLE_PORT(lane_least, lane_size_lg2) \
|
|
(((lane_least) << 3) | (lane_size_lg2))
|
|
#define TME_BUS_CYCLE_PORT_SIZE_LG2(port) \
|
|
TME_FIELD_EXTRACTU(port, 0, 3)
|
|
#define TME_BUS_CYCLE_PORT_LANE_LEAST(port) \
|
|
TME_FIELD_EXTRACTU(port, 3, 5)
|
|
};
|
|
|
|
/* a bus cycle handler: */
|
|
typedef int (*tme_bus_cycle_handler) _TME_P((void *, struct tme_bus_cycle *));
|
|
|
|
/* a bus fault handler: */
|
|
typedef int (*tme_bus_fault_handler) _TME_P((void *, struct tme_bus_tlb *, struct tme_bus_cycle *, int));
|
|
|
|
/* a bus cacheable: */
|
|
struct tme_bus_cacheable {
|
|
|
|
/* the cacheable contents and size: */
|
|
tme_shared tme_uint8_t *tme_bus_cacheable_contents;
|
|
unsigned long tme_bus_cacheable_size;
|
|
|
|
/* the cacheable private state: */
|
|
void *tme_bus_cacheable_private;
|
|
|
|
/* this function allocates a new valids bitmask: */
|
|
tme_shared tme_uint8_t *(*tme_bus_cacheable_valids_new) _TME_P((void *, tme_uint32_t));
|
|
|
|
/* this function sets a bit in the valids bitmask: */
|
|
void (*tme_bus_cacheable_valids_set) _TME_P((void *, tme_shared tme_uint8_t *, unsigned long));
|
|
};
|
|
|
|
/* a bus TLB entry: */
|
|
struct tme_bus_tlb {
|
|
|
|
/* the bus address region covered by this TLB entry: */
|
|
tme_bus_addr_t tme_bus_tlb_addr_first;
|
|
tme_bus_addr_t tme_bus_tlb_addr_last;
|
|
|
|
/* the token associated with this TLB entry: */
|
|
struct tme_token *tme_bus_tlb_token;
|
|
|
|
/* when one or both of these pointers are not TME_EMULATOR_OFF_UNDEF,
|
|
this TLB entry allows fast (memory) reads of and/or writes to the
|
|
bus region. adding an address in the bus region to one of these
|
|
pointers yields the desired host memory address: */
|
|
_tme_const tme_shared tme_uint8_t *tme_bus_tlb_emulator_off_read;
|
|
tme_shared tme_uint8_t *tme_bus_tlb_emulator_off_write;
|
|
|
|
/* fast (memory) reads and writes are protected by this rwlock: */
|
|
tme_rwlock_t *tme_bus_tlb_rwlock;
|
|
|
|
/* if non-NULL, this bus region is cacheable memory: */
|
|
_tme_const struct tme_bus_cacheable *tme_bus_tlb_cacheable;
|
|
|
|
/* when one or both of TLB_BUS_CYCLE_READ and TLB_BUS_CYCLE_WRITE
|
|
are set in this value, this TLB entry allows slow (function call)
|
|
reads of and/or writes to the bus region: */
|
|
unsigned int tme_bus_tlb_cycles_ok;
|
|
|
|
/* adding an address in the bus region to this offset, and then
|
|
shifting that result to the right (shift > 0) or to the left
|
|
(shift < 0) yields an address for the bus cycle handler: */
|
|
tme_bus_addr_t tme_bus_tlb_addr_offset;
|
|
int tme_bus_tlb_addr_shift;
|
|
|
|
/* the bus cycle handler: */
|
|
void *tme_bus_tlb_cycle_private;
|
|
tme_bus_cycle_handler tme_bus_tlb_cycle;
|
|
|
|
/* the bus fault handlers: */
|
|
unsigned int tme_bus_tlb_fault_handler_count;
|
|
struct {
|
|
void *tme_bus_tlb_fault_handler_private;
|
|
tme_bus_fault_handler tme_bus_tlb_fault_handler;
|
|
} tme_bus_tlb_fault_handlers[TME_BUS_TLB_FAULT_HANDLERS];
|
|
};
|
|
|
|
/* a bus signals set: */
|
|
struct tme_bus_signals {
|
|
|
|
/* the bus signals set identifier: */
|
|
tme_uint32_t tme_bus_signals_id;
|
|
|
|
/* the version of the bus signals: */
|
|
tme_uint32_t tme_bus_signals_version;
|
|
|
|
/* the maximum number of bus signals in the set: */
|
|
tme_uint32_t tme_bus_signals_count;
|
|
|
|
/* the first signal in the bus signals set: */
|
|
tme_uint32_t tme_bus_signals_first;
|
|
};
|
|
|
|
/* a bus master's TLB set information: */
|
|
struct tme_bus_tlb_set_info {
|
|
|
|
/* the first token in the set: */
|
|
struct tme_token *tme_bus_tlb_set_info_token0;
|
|
|
|
/* the stride between tokens in the set, in bytes: */
|
|
unsigned long tme_bus_tlb_set_info_token_stride;
|
|
|
|
/* the count of tokens in the set: */
|
|
unsigned long tme_bus_tlb_set_info_token_count;
|
|
|
|
/* the set's optional bus context register: */
|
|
/* NB: this isn't tme_shared because the bus context, when it does
|
|
exist, is only exposed to the one bus master that can actually
|
|
change it - and we assume that changing the bus context
|
|
synchronizes the master: */
|
|
tme_bus_context_t *tme_bus_tlb_set_info_bus_context;
|
|
|
|
/* the maximum value of the bus context register: */
|
|
tme_bus_context_t tme_bus_tlb_set_info_bus_context_max;
|
|
};
|
|
|
|
/* a bus connection: */
|
|
struct tme_bus_connection {
|
|
|
|
/* the generic connection side: */
|
|
struct tme_connection tme_bus_connection;
|
|
|
|
/* the subregions on the bus for this connection. most connections
|
|
will only have one subregion, with a first address of zero and a
|
|
last address of their size on the bus: */
|
|
struct tme_bus_subregion {
|
|
|
|
/* the first and last addresses, starting from zero, of this
|
|
subregion: */
|
|
tme_bus_addr_t tme_bus_subregion_address_first;
|
|
tme_bus_addr_t tme_bus_subregion_address_last;
|
|
|
|
/* any other subregions for this bus connection: */
|
|
_tme_const struct tme_bus_subregion *tme_bus_subregion_next;
|
|
} tme_bus_subregions;
|
|
|
|
/* the bus signal set adder: */
|
|
int (*tme_bus_signals_add) _TME_P((struct tme_bus_connection *,
|
|
struct tme_bus_signals *));
|
|
|
|
/* the bus signal handler: */
|
|
int (*tme_bus_signal) _TME_P((struct tme_bus_connection *, unsigned int));
|
|
|
|
/* the bus interrupt acknowledge handler: */
|
|
int (*tme_bus_intack) _TME_P((struct tme_bus_connection *, unsigned int, int *));
|
|
|
|
/* the bus TLB set add handler: */
|
|
int (*tme_bus_tlb_set_add) _TME_P((struct tme_bus_connection *, struct tme_bus_tlb_set_info *));
|
|
|
|
/* the bus TLB entry filler: */
|
|
int (*tme_bus_tlb_fill) _TME_P((struct tme_bus_connection *, struct tme_bus_tlb *,
|
|
tme_bus_addr_t, unsigned int));
|
|
};
|
|
|
|
/* internal information about a bus connection: */
|
|
struct tme_bus_connection_int {
|
|
|
|
/* the external bus connection: */
|
|
struct tme_bus_connection tme_bus_connection_int;
|
|
|
|
/* flags on the bus connection: */
|
|
int tme_bus_connection_int_flags;
|
|
|
|
/* the first and last addresses of this connection. most code
|
|
should never use the last-address value, and instead should honor
|
|
the connection's subregions: */
|
|
tme_bus_addr_t tme_bus_connection_int_address;
|
|
tme_bus_addr_t tme_bus_connection_int_address_last;
|
|
|
|
/* the mask added to addresses sourced by this connection: */
|
|
tme_bus_addr_t tme_bus_connection_int_sourced;
|
|
|
|
/* the single interrupt signal used by this connection, when
|
|
the connection doesn't know already: */
|
|
int tme_bus_connection_int_signal_int;
|
|
|
|
/* the single interrupt vector used by this connection, when the
|
|
connection doesn't know already: */
|
|
int tme_bus_connection_int_vector_int;
|
|
|
|
/* nonzero iff we've already logged an unconfigured interrupt
|
|
signal: */
|
|
int tme_bus_connection_int_logged_int;
|
|
|
|
/* the current status of the bus signals for this connection: */
|
|
tme_uint8_t *tme_bus_connection_int_signals;
|
|
};
|
|
|
|
/* a generic bus slot: */
|
|
struct tme_bus_slot {
|
|
|
|
/* generic bus slots are kept on a list: */
|
|
struct tme_bus_slot *tme_bus_slot_next;
|
|
|
|
/* the name of this bus slot: */
|
|
char *tme_bus_slot_name;
|
|
|
|
/* the address and size of this bus slot: */
|
|
tme_bus_addr_t tme_bus_slot_address;
|
|
tme_bus_addr_t tme_bus_slot_size;
|
|
};
|
|
|
|
/* a generic bus: */
|
|
struct tme_bus {
|
|
|
|
/* the optional rwlock protecting this bus: */
|
|
tme_rwlock_t tme_bus_rwlock;
|
|
|
|
/* the address mask used on this bus: */
|
|
tme_bus_addr_t tme_bus_address_mask;
|
|
|
|
/* all connections to this bus: */
|
|
struct tme_bus_connection_int *tme_bus_connections;
|
|
|
|
/* the number of addressable connections to this bus: */
|
|
int tme_bus_addressables_count;
|
|
|
|
/* the size of the addressable connections array: */
|
|
int tme_bus_addressables_size;
|
|
|
|
/* the addressable connections array: */
|
|
struct tme_bus_addressable {
|
|
struct tme_bus_connection_int *tme_bus_addressable_connection;
|
|
_tme_const struct tme_bus_subregion *tme_bus_addressable_subregion;
|
|
} *tme_bus_addressables;
|
|
|
|
/* the bus signal sets on this bus: */
|
|
unsigned int tme_bus_signals_count;
|
|
struct tme_bus_signals *tme_bus_signals;
|
|
|
|
/* the number of devices asserting the various bus signals: */
|
|
unsigned int *tme_bus_signal_asserts;
|
|
|
|
/* any bus slots: */
|
|
struct tme_bus_slot *tme_bus_slots;
|
|
|
|
/* any bus controller connection: */
|
|
struct tme_bus_connection_int *tme_bus_controller;
|
|
};
|
|
|
|
/* prototypes: */
|
|
int tme_bus_address_search _TME_P((struct tme_bus *, tme_bus_addr_t));
|
|
int tme_bus_connection_ok _TME_P((struct tme_bus *,
|
|
struct tme_bus_connection_int *));
|
|
int tme_bus_connection_make _TME_P((struct tme_bus *,
|
|
struct tme_bus_connection_int *,
|
|
unsigned int));
|
|
int tme_bus_connection_break _TME_P((struct tme_bus *,
|
|
struct tme_bus_connection_int *,
|
|
unsigned int));
|
|
int tme_bus_tlb_fill _TME_P((struct tme_bus *,
|
|
struct tme_bus_connection_int *,
|
|
struct tme_bus_tlb *, tme_bus_addr_t, unsigned int));
|
|
int tme_bus_tlb_set_add _TME_P((struct tme_bus *,
|
|
struct tme_bus_connection_int *,
|
|
struct tme_bus_tlb_set_info *));
|
|
void tme_bus_tlb_set_invalidate _TME_P((_tme_const struct tme_bus_tlb_set_info *));
|
|
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));
|
|
void tme_bus_tlb_initialize _TME_P((struct tme_bus_tlb *));
|
|
int tme_bus_tlb_fault _TME_P((struct tme_bus_tlb *, struct tme_bus_cycle *, int));
|
|
tme_bus_addr_t tme_bus_addr_parse _TME_P((_tme_const char *, tme_bus_addr_t));
|
|
tme_bus_addr_t tme_bus_addr_parse_any _TME_P((_tme_const char *, int *));
|
|
void tme_bus_cycle_xfer _TME_P((struct tme_bus_cycle *, struct tme_bus_cycle *));
|
|
void tme_bus_cycle_xfer_memory _TME_P((struct tme_bus_cycle *, tme_uint8_t *, tme_bus_addr_t));
|
|
void tme_bus_cycle_xfer_reg _TME_P((struct tme_bus_cycle *, void *, unsigned int));
|
|
|
|
#endif /* !_TME_GENERIC_BUS_H */
|