URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1371 to Rev 1372
- ↔ Reverse comparison
Rev 1371 → Rev 1372
/trunk/or1ksim/sim-config.h
24,7 → 24,6
|
/* Simulator configuration macros. Eventually this one will be a lot bigger. */ |
|
#define MAX_ETHERNETS 4 /* Max. number of Ethernet MACs */ |
#define MAX_GPIOS 4 /* Max. number of GPIO modules */ |
#define MAX_MEMORIES 16 /* Max. number of memory devices attached */ |
#define MAX_ATAS 4 /* Max. number of ATAS */ |
41,20 → 40,6
int enabled; /* Is tick timer enabled? */ |
} tick; |
|
int nethernets; |
struct { |
unsigned long baseaddr; |
int irq; /* IRQ of this device */ |
unsigned dma; /* Which controller is this ethernet "connected" to */ |
unsigned rtx_type; /* use file or socket interface */ |
unsigned tx_channel; /* DMA channel used for TX */ |
unsigned rx_channel; /* DMA channel used for RX */ |
char rxfile[STR_SIZE]; /* Filename for RX */ |
char txfile[STR_SIZE]; /* File for TX */ |
char sockif[STR_SIZE]; /* Socket Interface name ('lo', 'eth1',...) */ |
unsigned long base_vapi_id; /* VAPI id for this instance */ |
} ethernets[MAX_ETHERNETS]; |
|
int ngpios; |
struct { |
unsigned long baseaddr; /* Base address */ |
/trunk/or1ksim/sim.cfg
663,11 → 663,6
|
This section configures the ETHERNETs |
|
nethernets = <value> |
make specified number of instances, configure each |
instance within device - enddevice construct. |
|
instance specific: |
baseaddr = <hex_value> |
address of first ethernet register for this device |
|
700,19 → 695,15
*/ |
|
section ethernet |
nethernets = 1 |
|
device 0 |
baseaddr = 0x92000000 |
dma = 0 |
irq = 4 |
rtx_type = 1 |
tx_channel = 0 |
rx_channel = 1 |
rxfile = "eth0.rx" |
txfile = "eth0.tx" |
sockif = "eth0" |
enddevice |
baseaddr = 0x92000000 |
dma = 0 |
irq = 4 |
rtx_type = 1 |
tx_channel = 0 |
rx_channel = 1 |
rxfile = "eth0.rx" |
txfile = "eth0.tx" |
sockif = "eth0" |
end |
|
|
/trunk/or1ksim/sim-cmd.c
60,7 → 60,6
#include "icache_model.h" |
#include "dcache_model.h" |
#include "branch_predict.h" |
#include "ethernet.h" |
#include "gpio.h" |
|
struct sim_stat { |
421,7 → 420,6
if (config.bpb.btic) btic_info(); |
|
if (config.mc.enabled) mc_status(); |
if (config.nethernets) eth_status(); |
if (config.ngpios) gpio_status(); |
|
while(cur_stat) { |
/trunk/or1ksim/peripheral/eth.c
48,22 → 48,20
#include "crc32.h" |
#include "vapi.h" |
#include "pic.h" |
#include "sched.h" |
#include "debug.h" |
|
static struct eth_device eths[MAX_ETHERNETS]; |
DEFAULT_DEBUG_CHANNEL(eth); |
|
/* simulator interface */ |
static void eth_reset_controller( struct eth_device *eth); |
static void eth_vapi_read( unsigned long id, unsigned long data, void *dat); |
/* register interface */ |
static void eth_write32( oraddr_t addr, uint32_t value, void *dat ); |
static uint32_t eth_read32( oraddr_t addr, void *dat ); |
/* clock */ |
static void eth_controller_tx_clock( struct eth_device * ); |
static void eth_controller_rx_clock( struct eth_device * ); |
static void eth_controller_tx_clock( void * ); |
static void eth_controller_rx_clock( void * ); |
/* utility functions */ |
static int eth_find_controller( oraddr_t addr, struct eth_device **eth, oraddr_t *reladdr ); |
struct eth_device *eth_find_vapi_device (unsigned long id, unsigned long *which); |
static ssize_t eth_read_rx_file( struct eth_device *, void *, size_t ); |
static void eth_skip_rx_file( struct eth_device *, off_t ); |
static void eth_rewind_rx_file( struct eth_device *, off_t ); |
77,8 → 75,9
* TX clock |
* Responsible for starting and finishing TX |
*/ |
void eth_controller_tx_clock( struct eth_device *eth ) |
void eth_controller_tx_clock( void *dat ) |
{ |
struct eth_device *eth = dat; |
int breakpoint = 0; |
int bAdvance = 1; |
#if HAVE_ETH_PHY |
88,13 → 87,9
unsigned long read_word; |
|
switch (eth->tx.state) { |
case ETH_TXSTATE_IDLE: |
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, TXEN ) ) { |
|
/* wait for TxBuffer to be ready */ |
debug (3, "TX - entering state WAIT4BD (%ld)\n", eth->tx.bd_index); |
eth->tx.state = ETH_TXSTATE_WAIT4BD; |
} |
case ETH_TXSTATE_IDLE: |
debug (3, "TX - entering state WAIT4BD (%ld)\n", eth->tx.bd_index); |
eth->tx.state = ETH_TXSTATE_WAIT4BD; |
break; |
case ETH_TXSTATE_WAIT4BD: |
/* Read buffer descriptor */ |
156,11 → 151,6
debug (3, "TX - entering state READFIFO\n"); |
eth->tx.state = ETH_TXSTATE_READFIFO; |
} |
else if ( !TEST_FLAG( eth->regs.moder, ETH_MODER, TXEN ) ) { |
/* stop TX logic */ |
debug (3, "TX - entering state IDLE\n"); |
eth->tx.state = ETH_TXSTATE_IDLE; |
} |
|
/* stay in this state if (TXEN && !READY) */ |
break; |
205,8 → 195,8
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXB); |
debug (4, "ETH_INT_SOURCE = %0lx\n", eth->regs.int_source); |
|
debug (3, "TX - entering state IDLE\n"); |
eth->tx.state = ETH_TXSTATE_IDLE; |
debug (3, "TX - entering state WAIT4BD\n"); |
eth->tx.state = ETH_TXSTATE_WAIT4BD; |
debug (3, "send (%ld)bytes OK\n", nwritten); |
} |
else { |
216,8 → 206,8
SET_FLAG (eth->regs.int_source, ETH_INT_SOURCE, TXE); |
debug (4, "ETH_INT_SOURCE = %0lx\n", eth->regs.int_source); |
|
debug (3, "TX - entering state IDLE\n"); |
eth->tx.state = ETH_TXSTATE_IDLE; |
debug (3, "TX - entering state WAIT4BD\n"); |
eth->tx.state = ETH_TXSTATE_WAIT4BD; |
debug (3, "send FAILED!\n"); |
} |
|
242,6 → 232,9
|
break; |
} |
|
/* Reschedule */ |
SCHED_ADD( eth_controller_tx_clock, dat, runtime.sim.cycles + 1 ); |
} |
/* ========================================================================= */ |
|
254,8 → 247,9
* RX clock |
* Responsible for starting and finishing RX |
*/ |
void eth_controller_rx_clock( struct eth_device *eth ) |
void eth_controller_rx_clock( void *dat ) |
{ |
struct eth_device *eth = dat; |
int breakpoint = 0; |
long nread; |
unsigned long send_word; |
263,10 → 257,8
|
switch (eth->rx.state) { |
case ETH_RXSTATE_IDLE: |
if ( TEST_FLAG( eth->regs.moder, ETH_MODER, RXEN) ) { |
debug (3, "RX - entering state WAIT4BD (%ld)\n", eth->rx.bd_index); |
eth->rx.state = ETH_RXSTATE_WAIT4BD; |
} |
debug (3, "RX - entering state WAIT4BD (%ld)\n", eth->rx.bd_index); |
eth->rx.state = ETH_RXSTATE_WAIT4BD; |
break; |
|
case ETH_RXSTATE_WAIT4BD: |
328,8 → 320,8
debug( 3, "eth_start_rx(): Packet too small\n" ); |
eth_rx_next_packet( eth ); |
|
debug (3, "RX - entering state IDLE\n"); |
eth->rx.state = ETH_RXSTATE_IDLE; |
debug (3, "RX - entering state WAIT4BD\n"); |
eth->rx.state = ETH_RXSTATE_WAIT4BD; |
break; |
} |
|
442,6 → 434,9
} |
break; |
} |
|
/* Reschedule */ |
SCHED_ADD( eth_controller_rx_clock, dat, runtime.sim.cycles + 1 ); |
} |
|
/* ========================================================================= */ |
496,61 → 491,18
Reset. Initializes all registers to default and places devices in |
memory address space. |
*/ |
void eth_reset() |
void eth_reset(void *dat) |
{ |
static int first_time = 1; |
unsigned i; |
|
if (!config.nethernets) |
return; |
|
if ( first_time ) |
memset( eths, 0, sizeof(eths) ); |
|
for ( i = 0; i < MAX_ETHERNETS; ++ i ) { |
struct eth_device *eth = &(eths[i]); |
|
if (!HAVE_ETH_PHY && eth->rtx_type == ETH_RTX_SOCK) { |
fprintf (stderr, "Ethernet phy not enabled in this configuration. Configure with --enable-ethphy.\n"); |
exit (1); |
} |
eth->eth_number = i; |
eth_reset_controller( eth ); |
if ( eth->baseaddr && first_time ) |
register_memoryarea( eth->baseaddr, ETH_ADDR_SPACE, 4, 0, eth_read32, eth_write32, NULL ); |
} |
|
if ( first_time ) |
first_time = 0; |
} |
|
/* ========================================================================= */ |
|
|
static void eth_reset_controller(struct eth_device *eth) |
{ |
int i = eth->eth_number; |
struct eth_device *eth = dat; |
#if HAVE_ETH_PHY |
int j; |
struct sockaddr_ll sll; |
#endif /* HAVE_ETH_PHY */ |
|
eth->baseaddr = config.ethernets[i].baseaddr; |
|
if ( eth->baseaddr != 0 ) { |
/* Mark which DMA controller and channels */ |
eth->dma = config.ethernets[i].dma; |
eth->mac_int = config.ethernets[i].irq; |
eth->tx_channel = config.ethernets[i].tx_channel; |
eth->rx_channel = config.ethernets[i].rx_channel; |
eth->rtx_type = config.ethernets[i].rtx_type; |
|
switch (eth->rtx_type) { |
case ETH_RTX_FILE: |
/* (Re-)open TX/RX files */ |
eth->rxfile = config.ethernets[i].rxfile; |
eth->txfile = config.ethernets[i].txfile; |
|
if ( eth->rxfd > 0 ) |
close( eth->rxfd ); |
if ( eth->txfd > 0 ) |
587,7 → 539,7
/* get interface index number */ |
debug (3, "RTX getting interface...\n"); |
memset(&(eth->ifr), 0, sizeof(eth->ifr)); |
strncpy(eth->ifr.ifr_name, config.ethernets[i].sockif, IFNAMSIZ); |
strncpy(eth->ifr.ifr_name, eth->sockif, IFNAMSIZ); |
if (ioctl(eth->rtx_sock, SIOCGIFINDEX, &(eth->ifr)) == -1) { |
fprintf( stderr, "SIOCGIFINDEX failed!\n"); |
return; |
622,6 → 574,11
debug (3, "\n"); |
|
break; |
#else /* HAVE_ETH_PHY */ |
case ETH_RTX_SOCK: |
fprintf (stderr, "Ethernet phy not enabled in this configuration. Configure with --enable-ethphy.\n"); |
exit (1); |
break; |
#endif /* HAVE_ETH_PHY */ |
} |
|
642,9 → 599,8
eth->rx.bd_index = eth->regs.tx_bd_num << 1; |
|
/* Initialize VAPI */ |
if (config.ethernets[i].base_vapi_id) { |
eth->base_vapi_id = config.ethernets[i].base_vapi_id; |
vapi_install_multi_handler( eth->base_vapi_id, ETH_NUM_VAPI_IDS, eth_vapi_read, NULL ); |
if (eth->base_vapi_id) { |
vapi_install_multi_handler( eth->base_vapi_id, ETH_NUM_VAPI_IDS, eth_vapi_read, dat ); |
} |
} |
} |
654,68 → 610,43
/* |
Print register values on stdout |
*/ |
void eth_status( void ) |
void eth_status( void *dat ) |
{ |
unsigned i; |
struct eth_device *eth = dat; |
|
for ( i = 0; i < MAX_ETHERNETS; ++ i ) { |
struct eth_device *eth = &(eths[i]); |
|
if ( eth->baseaddr == 0 ) |
continue; |
|
PRINTF( "\nEthernet MAC %u at 0x%"PRIxADDR":\n", i, eth->baseaddr ); |
PRINTF( "MODER : 0x%08lX\n", eth->regs.moder ); |
PRINTF( "INT_SOURCE : 0x%08lX\n", eth->regs.int_source ); |
PRINTF( "INT_MASK : 0x%08lX\n", eth->regs.int_mask ); |
PRINTF( "IPGT : 0x%08lX\n", eth->regs.ipgt ); |
PRINTF( "IPGR1 : 0x%08lX\n", eth->regs.ipgr1 ); |
PRINTF( "IPGR2 : 0x%08lX\n", eth->regs.ipgr2 ); |
PRINTF( "PACKETLEN : 0x%08lX\n", eth->regs.packetlen ); |
PRINTF( "COLLCONF : 0x%08lX\n", eth->regs.collconf ); |
PRINTF( "TX_BD_NUM : 0x%08lX\n", eth->regs.tx_bd_num ); |
PRINTF( "CTRLMODER : 0x%08lX\n", eth->regs.controlmoder ); |
PRINTF( "MIIMODER : 0x%08lX\n", eth->regs.miimoder ); |
PRINTF( "MIICOMMAND : 0x%08lX\n", eth->regs.miicommand ); |
PRINTF( "MIIADDRESS : 0x%08lX\n", eth->regs.miiaddress ); |
PRINTF( "MIITX_DATA : 0x%08lX\n", eth->regs.miitx_data ); |
PRINTF( "MIIRX_DATA : 0x%08lX\n", eth->regs.miirx_data ); |
PRINTF( "MIISTATUS : 0x%08lX\n", eth->regs.miistatus ); |
PRINTF( "MAC Address : %02X:%02X:%02X:%02X:%02X:%02X\n", |
eth->mac_address[0], eth->mac_address[1], eth->mac_address[2], |
eth->mac_address[3], eth->mac_address[4], eth->mac_address[5] ); |
PRINTF( "HASH0 : 0x%08lX\n", eth->regs.hash0 ); |
PRINTF( "HASH1 : 0x%08lX\n", eth->regs.hash1 ); |
} |
PRINTF( "\nEthernet MAC at 0x%"PRIxADDR":\n", eth->baseaddr ); |
PRINTF( "MODER : 0x%08lX\n", eth->regs.moder ); |
PRINTF( "INT_SOURCE : 0x%08lX\n", eth->regs.int_source ); |
PRINTF( "INT_MASK : 0x%08lX\n", eth->regs.int_mask ); |
PRINTF( "IPGT : 0x%08lX\n", eth->regs.ipgt ); |
PRINTF( "IPGR1 : 0x%08lX\n", eth->regs.ipgr1 ); |
PRINTF( "IPGR2 : 0x%08lX\n", eth->regs.ipgr2 ); |
PRINTF( "PACKETLEN : 0x%08lX\n", eth->regs.packetlen ); |
PRINTF( "COLLCONF : 0x%08lX\n", eth->regs.collconf ); |
PRINTF( "TX_BD_NUM : 0x%08lX\n", eth->regs.tx_bd_num ); |
PRINTF( "CTRLMODER : 0x%08lX\n", eth->regs.controlmoder ); |
PRINTF( "MIIMODER : 0x%08lX\n", eth->regs.miimoder ); |
PRINTF( "MIICOMMAND : 0x%08lX\n", eth->regs.miicommand ); |
PRINTF( "MIIADDRESS : 0x%08lX\n", eth->regs.miiaddress ); |
PRINTF( "MIITX_DATA : 0x%08lX\n", eth->regs.miitx_data ); |
PRINTF( "MIIRX_DATA : 0x%08lX\n", eth->regs.miirx_data ); |
PRINTF( "MIISTATUS : 0x%08lX\n", eth->regs.miistatus ); |
PRINTF( "MAC Address : %02X:%02X:%02X:%02X:%02X:%02X\n", |
eth->mac_address[0], eth->mac_address[1], eth->mac_address[2], |
eth->mac_address[3], eth->mac_address[4], eth->mac_address[5] ); |
PRINTF( "HASH0 : 0x%08lX\n", eth->regs.hash0 ); |
PRINTF( "HASH1 : 0x%08lX\n", eth->regs.hash1 ); |
} |
/* ========================================================================= */ |
|
|
/* |
Simulation hook. Must be called every clock cycle to simulate Ethernet MAC. |
*/ |
void eth_clock() |
{ |
unsigned i; |
|
for ( i = 0; i < config.nethernets; ++ i ) { |
eth_controller_tx_clock( &(eths[i]) ); |
eth_controller_rx_clock( &(eths[i]) ); |
} |
} |
/* ========================================================================= */ |
|
|
/* |
Read a register |
*/ |
uint32_t eth_read32( oraddr_t addr, void *dat ) |
{ |
struct eth_device *eth; |
if ( !eth_find_controller( addr, ð, &addr ) ) { |
PRINTF( "eth_read32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr ); |
return 0; |
} |
struct eth_device *eth = dat; |
addr -= eth->baseaddr; |
|
switch( addr ) { |
case ETH_MODER: return eth->regs.moder; |
761,14 → 692,30
*/ |
void eth_write32( oraddr_t addr, uint32_t value, void *dat ) |
{ |
struct eth_device *eth; |
if ( !eth_find_controller( addr, ð, &addr ) ) { |
PRINTF( "eth_write32( 0x%"PRIxADDR" ): Not in registered range(s)\n", addr ); |
return; |
} |
|
struct eth_device *eth = dat; |
|
addr -= eth->baseaddr; |
|
switch( addr ) { |
case ETH_MODER: eth->regs.moder = value; if (TEST_FLAG(value, ETH_MODER, RST)) eth_reset(); return; |
case ETH_MODER: |
|
if ( !TEST_FLAG( eth->regs.moder, ETH_MODER, RXEN) && |
TEST_FLAG( value, ETH_MODER, RXEN) ) |
SCHED_ADD( eth_controller_rx_clock, dat, runtime.sim.cycles + 1 ); |
else if ( !TEST_FLAG( value, ETH_MODER, RXEN) ) |
SCHED_FIND_REMOVE( eth_controller_rx_clock, dat); |
|
if ( !TEST_FLAG( eth->regs.moder, ETH_MODER, TXEN) && |
TEST_FLAG( value, ETH_MODER, TXEN) ) |
SCHED_ADD( eth_controller_tx_clock, dat, runtime.sim.cycles + 1 ); |
else if ( !TEST_FLAG( value, ETH_MODER, TXEN) ) |
SCHED_FIND_REMOVE( eth_controller_tx_clock, dat); |
|
eth->regs.moder = value; |
|
if (TEST_FLAG(value, ETH_MODER, RST)) |
eth_reset( dat ); |
return; |
case ETH_INT_SOURCE: eth->regs.int_source &= ~value; return; |
case ETH_INT_MASK: eth->regs.int_mask = value; return; |
case ETH_IPGT: eth->regs.ipgt = value; return; |
819,8 → 766,10
static void eth_vapi_read (unsigned long id, unsigned long data, void *dat) |
{ |
unsigned long which; |
struct eth_device *eth = eth_find_vapi_device( id, &which ); |
struct eth_device *eth = dat; |
|
which = id - eth->base_vapi_id; |
|
debug( 5, "ETH: id %08lx, data %08lx\n", id, data ); |
|
if ( !eth ) { |
844,142 → 793,105
eth->regs.tx_bd_num = value & 0xFF; |
eth->rx.bd_index = eth->regs.tx_bd_num << 1; |
} |
|
/* ========================================================================= */ |
|
|
/* |
Convert a memory address to a oontroller struct and relative address. |
Return nonzero on success |
*/ |
int eth_find_controller( oraddr_t addr, struct eth_device **eth, oraddr_t *reladdr ) |
/*-----------------------------------------------[ Ethernet configuration ]---*/ |
void eth_baseaddr(union param_val val, void *dat) |
{ |
unsigned i; |
*eth = NULL; |
|
for ( i = 0; i < MAX_ETHERNETS && *eth == NULL; ++ i ) { |
if ( (addr >= eths[i].baseaddr) && (addr < eths[i].baseaddr + ETH_ADDR_SPACE) ) |
*eth = &(eths[i]); |
} |
|
/* verify we found a controller */ |
if ( *eth == NULL ) |
return 0; |
|
/* Verify legal address */ |
if ( (addr - (*eth)->baseaddr) % 4 != 0 ) |
return 0; |
|
*reladdr = addr - (*eth)->baseaddr; |
return 1; |
struct eth_device *eth = dat; |
eth->baseaddr = val.addr_val; |
} |
|
/* |
* Convert VAPI id to controller struct and relative address. |
*/ |
struct eth_device *eth_find_vapi_device( unsigned long id, unsigned long *which ) |
void eth_dma(union param_val val, void *dat) |
{ |
unsigned i; |
|
for ( i=0; i<config.nethernets; i++) { |
if ( (id>=eths[i].base_vapi_id) && (id < eths[i].base_vapi_id + ETH_NUM_VAPI_IDS)) { |
*which = id - eths[i].base_vapi_id; |
return &(eths[i]); |
} |
} |
|
return NULL; |
struct eth_device *eth = dat; |
eth->dma = val.addr_val; |
} |
|
/*-----------------------------------------------[ Ethernet configuration ]---*/ |
void eth_nethernets (union param_val val, void *dat) { |
if (val.int_val >= 0 && val.int_val < MAX_ETHERNETS) |
config.nethernets = val.int_val; |
else |
CONFIG_ERROR("invalid number of devices."); |
void eth_rtx_type(union param_val val, void *dat) |
{ |
struct eth_device *eth = dat; |
eth->rtx_type = val.int_val; |
} |
|
void eth_baseaddr (union param_val val, void *dat) { |
if (current_device >= 0 && current_device < config.nethernets) |
config.ethernets[current_device].baseaddr = val.addr_val; |
else |
CONFIG_ERROR("invalid device number."); |
void eth_rx_channel(union param_val val, void *dat) |
{ |
struct eth_device *eth = dat; |
eth->rx_channel = val.int_val; |
} |
|
void eth_dma (union param_val val, void *dat) { |
if (current_device >= 0 && current_device < config.nethernets) |
config.ethernets[current_device].dma = val.int_val; |
else |
CONFIG_ERROR("invalid device number."); |
void eth_tx_channel(union param_val val, void *dat) |
{ |
struct eth_device *eth = dat; |
eth->tx_channel = val.int_val; |
} |
|
void eth_rtx_type (union param_val val, void *dat) { |
if (current_device >= 0 && current_device < config.nethernets) |
config.ethernets[current_device].rtx_type = val.int_val; |
else |
CONFIG_ERROR("invalid device number."); |
void eth_rxfile(union param_val val, void *dat) |
{ |
struct eth_device *eth = dat; |
if(!(eth->rxfile = strdup(val.str_val))) { |
fprintf(stderr, "Peripheral Ethernet: Run out of memory\n"); |
exit(-1); |
} |
} |
|
void eth_rx_channel (union param_val val, void *dat) { |
if (current_device >= 0 && current_device < config.nethernets) |
config.ethernets[current_device].rx_channel = val.int_val; |
else |
CONFIG_ERROR("invalid device number."); |
} |
|
void eth_tx_channel (union param_val val, void *dat) { |
if (current_device >= 0 && current_device < config.nethernets) |
config.ethernets[current_device].rx_channel = val.int_val; |
else |
CONFIG_ERROR("invalid device number."); |
} |
|
void eth_rxfile (union param_val val, void *dat) { |
if (current_device >= 0 && current_device < config.nethernets) |
strcpy (config.ethernets[current_device].rxfile, val.str_val); |
else |
CONFIG_ERROR("invalid device number."); |
} |
|
void eth_txfile(union param_val val, void *dat) |
{ |
if (current_device >= 0 && current_device < config.nethernets) |
strcpy (config.ethernets[current_device].txfile, val.str_val); |
else |
CONFIG_ERROR("invalid device number."); |
struct eth_device *eth = dat; |
if(!(eth->txfile = strdup(val.str_val))) { |
fprintf(stderr, "Peripheral Ethernet: Run out of memory\n"); |
exit(-1); |
} |
} |
|
void eth_sockif(union param_val val, void *dat) |
{ |
if (current_device >= 0 && current_device < config.nethernets) |
strcpy (config.ethernets[current_device].sockif, val.str_val); |
else |
CONFIG_ERROR("invalid device number."); |
struct eth_device *eth = dat; |
if(!(eth->sockif = strdup(val.str_val))) { |
fprintf(stderr, "Peripheral Ethernet: Run out of memory\n"); |
exit(-1); |
} |
} |
|
void eth_irq(union param_val val, void *dat) |
{ |
if (current_device >= 0 && current_device < config.nethernets) |
config.ethernets[current_device].irq = val.int_val; |
else |
CONFIG_ERROR("invalid device number."); |
struct eth_device *eth = dat; |
eth->mac_int = val.int_val; |
} |
|
void eth_vapi_id(union param_val val, void *dat) |
{ |
if (current_device >= 0 && current_device < config.nethernets) |
config.ethernets[current_device].base_vapi_id = val.int_val; |
else |
CONFIG_ERROR("invalid device number."); |
struct eth_device *eth = dat; |
eth->base_vapi_id = val.int_val; |
} |
|
void *eth_sec_start(void) |
{ |
struct eth_device *new = malloc(sizeof(struct eth_device)); |
|
if(!new) { |
fprintf(stderr, "Peripheral Eth: Run out of memory\n"); |
exit(-1); |
} |
|
return new; |
} |
|
void eth_sec_end(void *dat) |
{ |
struct eth_device *eth = dat; |
|
register_memoryarea( eth->baseaddr, ETH_ADDR_SPACE, 4, 0, eth_read32, eth_write32, dat ); |
reg_sim_stat( eth_status, dat ); |
reg_sim_reset( eth_reset, dat ); |
} |
|
void reg_ethernet_sec(void) |
{ |
struct config_section *sec = reg_config_sec("ethernet", NULL, NULL); |
struct config_section *sec = reg_config_sec("ethernet", eth_sec_start, eth_sec_end); |
|
reg_config_param(sec, "nethernets", paramt_int, eth_nethernets); |
reg_config_param(sec, "device", paramt_int, change_device); |
reg_config_param(sec, "irq", paramt_int, eth_irq); |
reg_config_param(sec, "enddevice", paramt_int, end_device); |
reg_config_param(sec, "baseaddr", paramt_int, eth_baseaddr); |
reg_config_param(sec, "dma", paramt_int, eth_dma); |
reg_config_param(sec, "rtx_type", paramt_int, eth_rtx_type); |
/trunk/or1ksim/peripheral/ethernet_i.h
131,9 → 131,6
/* Base address in memory */ |
oraddr_t baseaddr; |
|
/* Which Ethernet MAC is this? */ |
unsigned eth_number; |
|
/* Which DMA controller is this MAC connected to */ |
unsigned dma; |
unsigned tx_channel; |
149,11 → 146,14
unsigned long base_vapi_id; |
|
/* RX and TX file names and handles */ |
const char *rxfile, *txfile; |
char *rxfile, *txfile; |
int txfd; |
int rxfd; |
off_t loopback_offset; |
|
/* Socket interface name */ |
char *sockif; |
|
int rtx_sock; |
int rtx_type; |
struct ifreq ifr; |
/trunk/or1ksim/peripheral/ethernet.h
21,12 → 21,6
#ifndef __OR1KSIM_PERIPHERAL_ETHERNET_H |
#define __OR1KSIM_PERIPHERAL_ETHERNET_H |
|
/* Exported function prototypes */ |
void eth_reset( void ); |
void eth_clock( void ); |
void eth_status( void ); |
|
|
/* Address space required by one Ethernet MAC */ |
#define ETH_ADDR_SPACE 0x1000 |
|
/trunk/or1ksim/toplevel.c
55,7 → 55,6
#include "profiler.h" |
#include "mprofiler.h" |
#include "mc.h" |
#include "ethernet.h" |
#include "gpio.h" |
#include "pm.h" |
#include "pic.h" |
71,7 → 70,7
#include "cuc.h" |
|
/* CVS revision number. */ |
const char rcsrev[] = "$Revision: 1.112 $"; |
const char rcsrev[] = "$Revision: 1.113 $"; |
|
inline void debug(int level, const char *format, ...) |
{ |
167,7 → 166,6
cur_reset = cur_reset->next; |
} |
|
eth_reset(); |
gpio_reset(); |
tick_reset(); |
pm_reset(); |
443,7 → 441,6
if (config.ic.enabled) ic_clock(); |
} |
|
if (config.ethernets) eth_clock(); |
if (config.ngpios) gpio_clock(); |
if (config.vapi.enabled && runtime.vapi.enabled) vapi_check(); |
if (config.debug.gdb_enabled) HandleServerSocket(false); /* block & check_stdin = false */ |
/trunk/or1ksim/sim-config.c
144,9 → 144,6
config.vapi.enabled = 0; |
strcpy (config.vapi.vapi_fn, "vapi.log"); |
|
/* Ethernet */ |
config.nethernets = 0; |
|
/* GPIO */ |
config.ngpios = 0; |
|
895,16 → 892,6
|
fprintf (f, " tick:{enabled:%i},\n", config.tick.enabled); |
|
fprintf (f, " nethernets:%i, ethernets:{", config.nethernets); |
comma = 0; |
for (i = 0; i < config.nethernets; i++) { |
fprintf (f, "%s\n {baseaddr:0x%08lx, dma:%i, tx_channel:0x%08x, rx_channel:0x%08x, rxfile:\"%s\", txfile:\"%s\", vapi_id:0x%08lx}", |
comma ? "," :"", config.ethernets[i].baseaddr, config.ethernets[i].dma, config.ethernets[i].tx_channel, config.ethernets[i].rx_channel, |
config.ethernets[i].rxfile, config.ethernets[i].txfile, config.ethernets[i].base_vapi_id); |
comma = 1; |
} |
fprintf (f, "},\n"); |
|
fprintf (f, " ngpios:%i, gpios:{", config.ngpios); |
comma = 0; |
for (i = 0; i < config.ngpios; i++) { |