OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openrisc/trunk/orpsocv2/sw
    from Rev 528 to Rev 530
    Reverse comparison

Rev 528 → Rev 530

/tests/ethmac/board/ethmac-ping.c
45,6 → 45,7
#include "printf.h"
#include "eth-phy-mii.h"
 
 
volatile unsigned tx_done;
static int next_tx_buf_num;
 
63,6 → 64,10
//#define OUR_IP_BYTES 0xac,0x1e,0x0,0x2 // 172.30.0.2
//#define OUR_IP_LONG 0xac1e0002
 
//#define OUR_IP_BYTES 0xa,0x0,0x0,0x14 // 10.0.0.20
//#define OUR_IP_LONG 0x0a000014
 
 
static char our_ip[4] = {OUR_IP_BYTES};
 
#define DEST_IP_BYTES 0xc0,0xa8,0x64,0x69 // 192 .168.100.105
69,10 → 74,12
//#define DEST_IP_BYTES 0xc0,0xa8,0x01,0x08 // 192 .168.1.8
//#define DEST_IP_BYTES 0xc0,0xa8,0x00,0x0f // 192 .168.0.15
//#define DEST_IP_BYTES 0xac,0x1e,0x0,0x01 // 172.30.0.1
//#define DEST_IP_BYTES 0xa,0x0,0x0,0x1 // 10.0.0.1
 
#define BCAST_DEST_IP_BYTES 0xc0,0xa8,0x64,0xff // 192.168.100.255
//#define BCAST_DEST_IP_BYTES 0xc0,0xa8,0x01,0xff // 192.168.1.255
//#define BCAST_DEST_IP_BYTES 0xc0,0xa8,0x00,0xff // 192.168.0.255
//#define BCAST_DEST_IP_BYTES 0xa,0x0,0x0,0xff // 10.0.0.255
 
/* Functions in this file */
void ethmac_setup(void);
88,6 → 95,8
 
// Global used to control whether we print out packets as we receive them
int print_packet_contents;
int packet_inspect_debug;
int print_ethmac_debug_reg;
 
/* Let the ethernet packets use a space beginning here for buffering */
#define ETH_BUFF_BASE 0x01000000
104,8 → 113,8
 
/* Buffer number (must be 2^n)
*/
#define OETH_RXBD_NUM 64
#define OETH_TXBD_NUM 64
#define OETH_RXBD_NUM 124
#define OETH_TXBD_NUM 4
#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1)
#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1)
 
137,6 → 146,82
// struct net_device_stats stats;
};
 
#define PRINT_BIT_NAME(bit,name) printf("%02d:"name" %d\n",bit,!!(reg&(1<<bit)))
void oeth_print_moder(unsigned long reg)
{
PRINT_BIT_NAME(16,"RECSMALL");
PRINT_BIT_NAME(15,"PAD");
PRINT_BIT_NAME(14,"HUGEN");
PRINT_BIT_NAME(13,"CRCEN");
PRINT_BIT_NAME(12,"DLYCRCEN");
PRINT_BIT_NAME(10,"FULLD");
PRINT_BIT_NAME(9,"EXDFREN");
PRINT_BIT_NAME(8,"NOBCKOF");
PRINT_BIT_NAME(7,"LOOPBCK");
PRINT_BIT_NAME(6,"IFG");
PRINT_BIT_NAME(5,"PRO");
PRINT_BIT_NAME(4,"IAM");
PRINT_BIT_NAME(3,"BRO");
PRINT_BIT_NAME(2,"NOPRE");
PRINT_BIT_NAME(1,"TXEN");
PRINT_BIT_NAME(0,"RXEN");
}
 
void oeth_print_intsource(unsigned long reg)
{
PRINT_BIT_NAME(6,"RXCtrlFrame");
PRINT_BIT_NAME(5,"TXCtrlFrame");
PRINT_BIT_NAME(4,"BUSY");
PRINT_BIT_NAME(3,"RXE");
PRINT_BIT_NAME(2,"RXB");
PRINT_BIT_NAME(1,"TXE");
PRINT_BIT_NAME(0,"TXB");
}
 
void oeth_print_ctrlmoder(unsigned long reg)
{
PRINT_BIT_NAME(2,"TXFLOW");
PRINT_BIT_NAME(1,"RXFLOW");
PRINT_BIT_NAME(0,"PASSALL");
}
 
void oeth_print_txbuf(unsigned long reg)
{
printf("RD%d ",!!(reg&(1<<15)));
printf("IQ%d ",!!(reg&(1<<14)));
printf("WP%d ",!!(reg&(1<<13)));
printf("PD%d ",!!(reg&(1<<12)));
printf("CC%d ",!!(reg&(1<<11)));
printf("UN%d ",!!(reg&(1<<8)));
printf("RY%d ",!!(reg&(1<<3)));
printf("LC%d ",!!(reg&(1<<2)));
printf("DF%d ",!!(reg&(1<<1)));
printf("CS%d ",!!(reg&(1<<0)));
printf("\n");
 
}
 
 
void oeth_print_rxbuf(unsigned long reg)
{
printf("EM%d ",!!(reg&(1<<15)));
printf("IQ%d ",!!(reg&(1<<14)));
printf("WP%d ",!!(reg&(1<<13)));
printf("PD%d ",!!(reg&(1<<12)));
printf("CF%d ",!!(reg&(1<<8)));
//printf("MS%d ",!!(reg&(1<<7)));
printf("OR%d ",!!(reg&(1<<6)));
printf("IS%d ",!!(reg&(1<<5)));
printf("DN%d ",!!(reg&(1<<4)));
printf("TL%d ",!!(reg&(1<<3)));
printf("SF%d ",!!(reg&(1<<2)));
printf("CE%d ",!!(reg&(1<<1)));
printf("LC%d ",!!(reg&(1<<0)));
printf("\n");
 
}
 
// PRINT_BIT_NAME(,"");
void oeth_printregs(void)
{
volatile oeth_regs *regs;
144,8 → 229,10
printf("Oeth regs: Mode Register : 0x%lx\n",
(unsigned long) regs->moder); /* Mode Register */
oeth_print_moder((unsigned long) regs->moder);
printf("Oeth regs: Interrupt Source Register 0x%lx\n",
(unsigned long) regs->int_src); /* Interrupt Source Register */
oeth_print_intsource((unsigned long) regs->int_src);
printf("Oeth regs: Interrupt Mask Register 0x%lx\n",
(unsigned long) regs->int_mask); /* Interrupt Mask Register */
printf("Oeth regs: Back to Bak Inter Packet Gap Register 0x%lx\n",
162,6 → 249,7
(unsigned long) regs->tx_bd_num); /* Transmit Buffer Descriptor Number Register */
printf("Oeth regs: Control Module Mode Register 0x%lx\n",
(unsigned long) regs->ctrlmoder); /* Control Module Mode Register */
oeth_print_ctrlmoder((unsigned long) regs->ctrlmoder);
printf("Oeth regs: MII Mode Register 0x%lx\n",
(unsigned long) regs->miimoder); /* MII Mode Register */
printf("Oeth regs: MII Command Register 0x%lx\n",
182,9 → 270,23
(unsigned long) regs->hash_addr0); /* Hash Register 0 */
printf("Oeth regs: Hash Register 1 0x%lx\n",
(unsigned long) regs->hash_addr1); /* Hash Register 1 */
printf("Oeth regs: TXCTRL 0x%lx\n",
(unsigned long) regs->txctrl); /* TX ctrl reg */
printf("Oeth regs: RXCTRL 0x%lx\n",
(unsigned long) regs->rxctrl); /* RX ctrl reg */
printf("Oeth regs: WBDBG 0x%lx\n",
(unsigned long) regs->wbdbg); /* Wishbone debug reg */
}
 
void oeth_print_wbdebug(void)
{
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
printf("Oeth regs: WBDBG 0x%lx\n",
(unsigned long) regs->wbdbg); /* Wishbone debug reg */
}
 
static int last_char;
 
void spin_cursor(void)
909,7 → 1011,61
return;
}
 
void oeth_ctrlmode_switch(void)
{
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
 
if (regs->ctrlmoder & (OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW))
{
printf("Disabling TX/RX flow control");
 
regs->ctrlmoder = 0;
}
else
{
printf("Enabling TX/RX flow control");
 
regs->ctrlmoder = (OETH_CTRLMODER_TXFLOW |
OETH_CTRLMODER_RXFLOW);
}
}
 
void
oeth_toggle_promiscuous(void)
{
// from arch/or32/drivers/open_eth.c
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
if ( regs->moder & OETH_MODER_PRO )
{
printf("Disabling ");
regs->moder &= ~OETH_MODER_PRO;
 
}
else
{
printf("Enabling ");
regs->moder |= OETH_MODER_PRO;
 
}
printf("promisucous mode\n");
}
 
void oeth_transmit_pause(void)
{
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
regs->txctrl = 0x1fffe;
}
 
 
void
ethmac_togglehugen(void)
{
982,7 → 1138,7
 
/* print packet contents */
static void
oeth_print_packet(unsigned long add, int len)
oeth_print_packet(int bd, unsigned long add, int len)
{
 
int truncate = (len > 256);
989,7 → 1145,7
int length_to_print = truncate ? 256 : len;
 
int i;
printf("\nipacket: add = %lx len = %d\n", add, len);
printf("\nbd%03d packet: add = %lx len = %d\n", bd,add, len);
for(i = 0; i < length_to_print; i++) {
if(!(i % 8))
printf(" ");
1062,7 → 1218,13
*/
tx_bd->len_status |= (OETH_TX_BD_READY | OETH_TX_BD_CRC | OETH_TX_BD_IRQ);
 
next_tx_buf_num = (next_tx_buf_num + 1) & OETH_TXBD_NUM_MASK;
//next_tx_buf_num = (next_tx_buf_num + 1) & OETH_TXBD_NUM_MASK;
next_tx_buf_num++;
if (next_tx_buf_num == OETH_TXBD_NUM)
{
next_tx_buf_num = 0;
}
 
return;
 
1090,7 → 1252,7
{
// Something in this buffer!
printf("Oeth: RX in buf %d - len_status: 0x%lx\n",i, rx_bd[i].len_status);
oeth_print_packet(rx_bd[i].addr, rx_bd[i].len_status >> 16);
oeth_print_packet(i,rx_bd[i].addr, rx_bd[i].len_status >> 16);
/* Clear recieved bit */
rx_bd[i].len_status |= OETH_RX_BD_EMPTY;
printf("\t end of packet\n\n");
1098,23 → 1260,36
}
}
 
#include "spr-defs.h"
 
/* Print out all buffer descriptors */
void oeth_dump_bds()
{
unsigned long* bd_base = (unsigned long*) OETH_BD_BASE;
// Disable interrupts
mtspr (SPR_SR, mfspr (SPR_SR) & ~SPR_SR_IEE);
 
int i;
for(i=0;i<OETH_TXBD_NUM;i++)
{
printf("oeth: tx_bd%d: len_status: %lx ",i,*bd_base++);
printf("addr: %lx\n", *bd_base++);
}
unsigned long* bd_base = (unsigned long*) OETH_BD_BASE;
 
for(i=0;i<OETH_RXBD_NUM;i++)
{
printf("oeth: rx_bd%d: len_status: %lx ",i,*bd_base++);
printf("addr: %lx\n", *bd_base++);
}
int i;
for(i=0;i<OETH_TXBD_NUM;i++)
{
printf("TXBD%03d len_status %08lx ",i,*bd_base);
oeth_print_txbuf(*bd_base++);
//printf("addr: %lx\n", *bd_base++);
*bd_base++;
}
 
for(i=0;i<OETH_RXBD_NUM;i++)
{
printf("RXBD%03d len_status %08lx ",i,*bd_base);
oeth_print_rxbuf(*bd_base++);
*bd_base++;
//printf("addr: %lx\n", *bd_base++);
}
 
// Enable interrupts
mtspr (SPR_SR, mfspr (SPR_SR) | SPR_SR_IEE);
}
 
1318,70 → 1493,89
oeth_interrupt(void)
{
 
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
 
uint int_events;
int serviced;
uint int_events;
int serviced;
serviced = 0;
serviced = 0;
 
/* Get the interrupt events that caused us to be here.
*/
int_events = regs->int_src;
regs->int_src = int_events;
/* Get the interrupt events that caused us to be here.
*/
int_events = regs->int_src;
regs->int_src = int_events;
 
 
/* Indicate busy */
if (int_events & OETH_INT_BUSY)
{
printf("\tBusy flag\n");
/*
printf("\n=tx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
((oeth_bd *)(OETH_BD_BASE))->len_status,
((oeth_bd *)(OETH_BD_BASE+8))->len_status,
((oeth_bd *)(OETH_BD_BASE+16))->len_status,
((oeth_bd *)(OETH_BD_BASE+24))->len_status,
((oeth_bd *)(OETH_BD_BASE+32))->len_status,
((oeth_bd *)(OETH_BD_BASE+40))->len_status,
((oeth_bd *)(OETH_BD_BASE+48))->len_status,
((oeth_bd *)(OETH_BD_BASE+56))->len_status);
*/
printf("=rx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
((oeth_bd *)(OETH_BD_BASE+64))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+8))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+16))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+24))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+32))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+40))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+48))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+56))->len_status);
/* Indicate busy */
if (int_events & OETH_INT_BUSY)
{
printf("\tBusy flag\n");
/*
printf("\n=tx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
((oeth_bd *)(OETH_BD_BASE))->len_status,
((oeth_bd *)(OETH_BD_BASE+8))->len_status,
((oeth_bd *)(OETH_BD_BASE+16))->len_status,
((oeth_bd *)(OETH_BD_BASE+24))->len_status,
((oeth_bd *)(OETH_BD_BASE+32))->len_status,
((oeth_bd *)(OETH_BD_BASE+40))->len_status,
((oeth_bd *)(OETH_BD_BASE+48))->len_status,
((oeth_bd *)(OETH_BD_BASE+56))->len_status);
*/
printf("=rx_ | %x | %x | %x | %x | %x | %x | %x | %x\n",
((oeth_bd *)(OETH_BD_BASE+64))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+8))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+16))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+24))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+32))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+40))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+48))->len_status,
((oeth_bd *)(OETH_BD_BASE+64+56))->len_status);
printf("=int | txb %d | txe %d | rxb %d | rxe %d | busy %d\n",
(int_events & OETH_INT_TXB) > 0,
(int_events & OETH_INT_TXE) > 0,
(int_events & OETH_INT_RXF) > 0,
(int_events & OETH_INT_RXE) > 0,
(int_events & OETH_INT_BUSY) > 0);
}
/* Handle receive event in its own function.
*/
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) {
serviced |= 0x1;
oeth_rx();
}
printf("=int | rxc %d | txc %d | txb %d | txe %d | rxb %d | rxe %d | busy %d\n",
(int_events & OETH_INT_RXC) > 0,
(int_events & OETH_INT_TXC) > 0,
(int_events & OETH_INT_TXB) > 0,
(int_events & OETH_INT_TXE) > 0,
(int_events & OETH_INT_RXF) > 0,
(int_events & OETH_INT_RXE) > 0,
(int_events & OETH_INT_BUSY) > 0);
}/*
else
printf("=int | rxc %d | txc %d | txb %d | txe %d | rxb %d | rxe %d | busy %d\n",
(int_events & OETH_INT_RXC) > 0,
(int_events & OETH_INT_TXC) > 0,
(int_events & OETH_INT_TXB) > 0,
(int_events & OETH_INT_TXE) > 0,
(int_events & OETH_INT_RXF) > 0,
(int_events & OETH_INT_RXE) > 0,
(int_events & OETH_INT_BUSY) > 0);
*/
/* Handle receive event in its own function.
*/
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) {
serviced |= 0x1;
if (print_ethmac_debug_reg)
oeth_print_wbdebug();
oeth_rx();
if (print_ethmac_debug_reg)
oeth_print_wbdebug();
}
 
/* Handle transmit event in its own function.
*/
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) {
serviced |= 0x2;
oeth_tx();
serviced |= 0x2;
/* Handle transmit event in its own function.
*/
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) {
if (print_ethmac_debug_reg)
oeth_print_wbdebug();
serviced |= 0x2;
oeth_tx();
serviced |= 0x2;
if (print_ethmac_debug_reg)
oeth_print_wbdebug();
}
}
return;
return;
}
 
// ARP stuff
1552,6 → 1746,10
// Check for ICMP echo request type
if (!(icmp->type == ICMP_TYPE_ECHO_REQ))
return;
 
// Skip forward to the target I.P address
if (packet_inspect_debug)
printf("Ping packet\n");
// Go ahead and construct a response packet
// Setup pointers
1701,11 → 1899,15
 
if (arp->ar_hrd == ARP_ETHER && arp->ar_op == ARPOP_REQUEST)
{
// Skip forward to the target I.P address
// Skip forward to the target I.P address
if (packet_inspect_debug)
printf("ARP packet\n");
char * internet_protocol_adr = (((unsigned long)&arp->ar_data[0]) + (arp->ar_hln * 2) + (arp->ar_pln));
char * internet_protocol_adr = (((unsigned long)&arp->ar_data[0]) +
(arp->ar_hln * 2) + (arp->ar_pln));
//printf("Is ARP ethernet request\ncheck adr at 0x%.8x\n",internet_protocol_adr);
//printf("Is ARP ethernet request\ncheck adr at 0x%.8x\n",
// internet_protocol_adr);
if ((internet_protocol_adr[0] == our_ip[0]) &&
(internet_protocol_adr[1] == our_ip[1]) &&
(internet_protocol_adr[2] == our_ip[2]) &&
1731,15 → 1933,18
reply_arp->ar_pln = 0x04;
reply_arp->ar_op = ARPOP_REPLY;
// My MAC
memcpy( (void*)&reply_arp->ar_data[0] , (void*)&reply_pkt->et_src , 6);
memcpy( (void*)&reply_arp->ar_data[0] ,
(void*)&reply_pkt->et_src , 6);
// My IP
memcpy( (void*)&reply_arp->ar_data[6] , (void*)&our_ip , 4);
// Their MAC
memcpy( (void*)&reply_arp->ar_data[10] , (void*)&eth_pkt->et_src , 6);
memcpy( (void*)&reply_arp->ar_data[10] ,
(void*)&eth_pkt->et_src , 6);
// Their IP
char * their_internet_protocol_adr =
(((unsigned long)&arp->ar_data[0]) + arp->ar_hln );
memcpy( (void*)&reply_arp->ar_data[16] , (void*)&their_internet_protocol_adr[0] , 4);
memcpy( (void*)&reply_arp->ar_data[16] ,
(void*)&their_internet_protocol_adr[0] , 4);
 
tx_packet((void*)arp_reply_packet,(ETHER_HDR_SIZE+ARP_HDR_SIZE) );
1753,74 → 1958,84
static void
oeth_rx(void)
{
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
 
volatile oeth_bd *rx_bdp;
int pkt_len, i;
int bad = 0;
volatile oeth_bd *rx_bdp;
int pkt_len, i;
int bad = 0;
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
if (print_packet_contents)
printf("rx");
if (print_packet_contents)
printf("rx ");
/* Find RX buffers marked as having received data */
for(i = 0; i < OETH_RXBD_NUM; i++)
{
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ /* Looking for NOT empty buffers desc. */
/* Check status for errors.
*/
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) {
bad = 1;
}
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) {
bad = 1;
}
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) {
bad = 1;
}
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) {
bad = 1;
}
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) {
/* Find RX buffers marked as having received data */
for(i = 0; i < OETH_RXBD_NUM; i++)
{
/* Looking for NOT empty buffers desc. */
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){
/* Check status for errors.
*/
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG |
OETH_RX_BD_SHORT)) {
bad = 1;
}
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) {
bad = 1;
}
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) {
bad = 1;
}
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) {
bad = 1;
}
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) {
}
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) {
bad = 1;
}
}
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) {
bad = 1;
}
if (bad) {
printf("RXE: 0x%x\n",rx_bdp[i].len_status & OETH_RX_BD_STATS);
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
bad = 0;
continue;
}
else {
if (bad) {
printf("RXE: 0x%x\n",rx_bdp[i].len_status &
OETH_RX_BD_STATS);
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
bad = 0;
continue;
}
else {
/* Process the incoming frame.
*/
pkt_len = rx_bdp[i].len_status >> 16;
/* Process the incoming frame.
*/
pkt_len = rx_bdp[i].len_status >> 16;
/* Do something here with the data - copy it into userspace, perhaps. */
// See if it's an ARP packet
packet_check_arp_header((void *)rx_bdp[i].addr );
// See if it's an ICMP echo request
packet_check_icmp_header((void *)rx_bdp[i].addr );
if (print_packet_contents)
{
oeth_print_packet(rx_bdp[i].addr, rx_bdp[i].len_status >> 16);
printf("\t end of packet\n\n");
}
/* finish up */
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */
/* Do something here with the data - copy it
into userspace, perhaps. */
// See if it's an ARP packet
packet_check_arp_header((void*)rx_bdp[i].addr);
// See if it's an ICMP echo request
packet_check_icmp_header((void*)rx_bdp[i].addr);
if (print_packet_contents)
{
oeth_print_packet(i, rx_bdp[i].addr,
rx_bdp[i].len_status
>> 16);
printf("\t end of packet\n\n");
}
/* finish up */
/* Clear stats */
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
/* Mark RX BD as empty */
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
 
oeth_transmit_pause(); //try this!
}
}
}
}
}
}
 
 
1828,33 → 2043,37
static void
oeth_tx(void)
{
volatile oeth_bd *tx_bd;
int i;
if (print_packet_contents)
printf("tx");
volatile oeth_bd *tx_bd;
int i;
if (print_packet_contents)
printf("tx");
 
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
/* Go through the TX buffs, search for one that was just sent */
for(i = 0; i < OETH_TXBD_NUM; i++)
{
/* Looking for buffer NOT ready for transmit. and IRQ enabled */
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) && (tx_bd[i].len_status & (OETH_TX_BD_IRQ)) )
/* Go through the TX buffs, search for one that was just sent */
for(i = 0; i < OETH_TXBD_NUM; i++)
{
//oeth_print_packet(tx_bd[i].addr, (tx_bd[i].len_status >> 16));
/* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
/* Looking for buffer NOT ready for transmit. and IRQ enabled */
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) &&
(tx_bd[i].len_status & (OETH_TX_BD_IRQ)) )
{
/* Single threaded so no chance we have detected a
buffer that has had its IRQ bit set but not its
BD_READ flag. Maybe this won't work in linux */
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
 
/* Probably good to check for TX errors here */
// Check if either carrier sense lost or colission indicated
if (tx_bd[i].len_status & OETH_TX_BD_STATS)
printf("TXER: 0x%x\n",(tx_bd[i].len_status & OETH_TX_BD_STATS));
/* Probably good to check for TX errors here */
// Check if either carrier sense lost or colission
// indicated
if (tx_bd[i].len_status & OETH_TX_BD_STATS)
printf("TXER: 0x%x\n",
(tx_bd[i].len_status &OETH_TX_BD_STATS));
if (print_packet_contents)
printf("T%d",i);
if (print_packet_contents)
printf("T%d",i);
}
}
}
return;
return;
}
 
 
1861,126 → 2080,157
int main ()
{
print_packet_contents = 0; // Default to not printing packet contents.
/* Initialise vector handler */
int_init();
print_packet_contents = 0; // Default to not printing packet contents.
packet_inspect_debug = 0;
print_ethmac_debug_reg = 0;
 
/* Install ethernet interrupt handler, it is enabled here too */
int_add(ETH0_IRQ, oeth_interrupt, 0);
/* Initialise vector handler */
int_init();
 
/* Enable interrupts */
cpu_enable_user_interrupts();
/* Install ethernet interrupt handler, it is enabled here too */
int_add(ETH0_IRQ, oeth_interrupt, 0);
 
/* Enable interrupts */
cpu_enable_user_interrupts();
last_char=0; /* Variable init for spin_cursor() */
next_tx_buf_num = 4; /* init for tx buffer counter */
last_char=0; /* Variable init for spin_cursor() */
next_tx_buf_num = 4; /* init for tx buffer counter */
 
uart_init(DEFAULT_UART); // init the UART before we can printf
printf("\n\teth ping program\n\n");
printf("\n\tboard IP: %d.%d.%d.%d\n",our_ip[0]&0xff,our_ip[1]&0xff,
our_ip[2]&0xff,our_ip[3]&0xff);
uart_init(DEFAULT_UART); // init the UART before we can printf
printf("\n\teth ping program\n\n");
printf("\n\tboard IP: %d.%d.%d.%d\n",our_ip[0]&0xff,our_ip[1]&0xff,
our_ip[2]&0xff,our_ip[3]&0xff);
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in MODER */
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX in
MODER */
//scan_ethphys(); /* Scan MIIM bus for PHYs */
//ethphy_init(); /* Attempt reset and configuration of PHY via MIIM */
//ethmac_scanstatus(); /* Enable scanning of status register via MIIM */
//scan_ethphys(); /* Scan MIIM bus for PHYs */
//ethphy_init(); /* Attempt reset and configuration of PHY via MIIM */
//ethmac_scanstatus(); /* Enable scanning of status register via MIIM */
 
/* Loop, monitoring user input from TTY */
while(1)
{
char c;
while(!uart_check_for_char(DEFAULT_UART))
/* Loop, monitoring user input from TTY */
while(1)
{
spin_cursor();
//oeth_monitor_rx();
}
char c;
c = uart_getc(DEFAULT_UART);
while(!uart_check_for_char(DEFAULT_UART))
{
spin_cursor();
if (print_ethmac_debug_reg)
oeth_print_wbdebug();
}
c = uart_getc(DEFAULT_UART);
 
if (c == 's')
tx_packet((void*) ping_packet, 98);
else if (c == 'S')
tx_packet((void*)big_ping_packet, 1514);
else if (c == 'h')
scan_ethphys();
else if (c == 'i')
ethphy_init();
else if (c == 'P')
{
print_packet_contents = print_packet_contents ? 0 : 1;
if (print_packet_contents)
printf("Enabling packet dumping\n");
else
printf("Packet dumping disabled\n");
}
else if (c == 'p')
oeth_printregs();
else if (c == '0')
scan_ethphy(0);
else if (c == '1')
scan_ethphy(1);
else if (c == '7')
{
//scan_ethphy(7);
//ethphy_print_status(7);
printf("ext_sr 0x%x\n",eth_mii_read(0x7, 0x1b));
}
else if (c == 'r')
{
ethphy_reset(7);
printf("PHY reset\n");
}
else if (c == 'R')
{
//oeth_reset_tx_bd_pointer();
ethmac_setup();
printf("MAC reset\n");
}
else if (c == 'n')
ethphy_reneg(7);
else if (c == 'N')
ethphy_set_autoneg(7);
else if (c == 'm')
ethmac_togglehugen();
else if (c == 't')
ethphy_set_10mbit(0);
else if (c == 'w')
{
// Play with HWCFG mode of Alaska 88e1111 Phy
c = uart_getc(DEFAULT_UART);
short newvalue;
// c is an ascii char, let's convert it to actual hex value
if (c >= 'A' && c <= 'F')
newvalue = c - (65 - 10);
else if (c >= 'a' && c <= 'f')
newvalue = c - (99 - 10);
else if (c >= '0' && c <= '9')
newvalue = c - 48;
if (c == 's')
tx_packet((void*) ping_packet, 98);
else if (c == 'S')
tx_packet((void*)big_ping_packet, 1514);
else if (c == 'h')
scan_ethphys();
else if (c == 'i')
ethphy_init();
else if (c == 'c')
oeth_ctrlmode_switch();
else if (c == 'P')
{
print_packet_contents = print_packet_contents ? 0 : 1;
if (print_packet_contents)
printf("Enabling packet dumping\n");
else
printf("Packet dumping disabled\n");
}
else if (c == 'p')
oeth_printregs();
else if (c == '0')
scan_ethphy(0);
else if (c == '1')
scan_ethphy(1);
else if (c == '7')
{
//scan_ethphy(7);
//ethphy_print_status(7);
printf("ext_sr 0x%x\n",eth_mii_read(0x7, 0x1b));
}
else if (c == 'r')
{
ethphy_reset(7);
printf("PHY reset\n");
}
else if (c == 'R')
{
//oeth_reset_tx_bd_pointer();
ethmac_setup();
printf("MAC reset\n");
}
else if (c == 'n')
ethphy_reneg(7);
else if (c == 'N')
ethphy_set_autoneg(7);
else if (c == 'm')
ethmac_togglehugen();
else if (c == 't')
ethphy_set_10mbit(0);
else if (c == 'w')
{
// Play with HWCFG mode of Alaska 88e1111 Phy
c = uart_getc(DEFAULT_UART);
short newvalue;
// c is an ascii char, let's convert it to actual hex
// value
if (c >= 'A' && c <= 'F')
newvalue = c - (65 - 10);
else if (c >= 'a' && c <= 'f')
newvalue = c - (99 - 10);
else if (c >= '0' && c <= '9')
newvalue = c - 48;
 
// Take this value and or it into the bottom bit (supposedly ext_sr)
// Take this value and or it into the bottom bit
// (supposedly ext_sr)
#define MII_M1111_PHY_EXT_SR 0x1b
short ext_sr;
ext_sr = eth_mii_read(0x7, MII_M1111_PHY_EXT_SR);
short ext_sr;
ext_sr = eth_mii_read(0x7, MII_M1111_PHY_EXT_SR);
#define MII_M1111_HWCFG_MODE_MASK 0xf
ext_sr &= ~MII_M1111_HWCFG_MODE_MASK;
ext_sr |= (short) newvalue;
eth_mii_write(0x7, MII_M1111_PHY_EXT_SR, ext_sr);
printf("ext_sr updated to - 0x%x\n",eth_mii_read(0x7, MII_M1111_PHY_EXT_SR));
}
else if ( c == 'b' )
{
printf("\n\t---\n");
oeth_dump_bds();
printf("\t---\n");
}
ext_sr &= ~MII_M1111_HWCFG_MODE_MASK;
ext_sr |= (short) newvalue;
eth_mii_write(0x7, MII_M1111_PHY_EXT_SR, ext_sr);
printf("ext_sr updated to - 0x%x\n",
eth_mii_read(0x7, MII_M1111_PHY_EXT_SR));
}
else if ( c == 'b' )
{
printf("\n\t---\n");
oeth_dump_bds();
printf("\t---\n");
}
else if ( c == 'B' )
{
tx_packet((void*) broadcast_ping_packet, 298);
else if ( c == 'B' )
{
tx_packet((void*) broadcast_ping_packet, 298);
}
else if (c == 'u' )
oeth_transmit_pause();
else if (c == 'd' )
{
oeth_print_wbdebug();
print_ethmac_debug_reg = !print_ethmac_debug_reg;
}
else if (c == 'v' )
{
if (packet_inspect_debug)
printf("Disabling ");
else
printf("Enabling ");
printf("packet type announcments\n");
packet_inspect_debug = !packet_inspect_debug;
}
else if ( c == 'o' )
oeth_toggle_promiscuous();
 
}
 
}
 
}
/tests/ethmac/sim/ethmac-rxtxcallresponse.c
5,10 → 5,6
//// Description ////
//// Send packets while receiving packets ////
//// ////
//// Test data comes from pre-calculated array of random values, ////
//// MAC TX buffer pointers are set to addresses in this array, ////
//// saving copying the data around before transfers. ////
//// ////
//// Author(s): ////
//// - jb, jb@orsoc.se, with parts taken from Linux kernel ////
//// open_eth driver. ////
479,6 → 475,7
report(0xbaad0004);
}
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) {
// not necessarily an issue
report(0xbaad0005);
}
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) {
636,7 → 633,7
send_ethmac_rxtx_test_init_packet(0x0); // 0x0 - call response test
#define ETH_TX_MIN_PACKET_SIZE 512
#define ETH_TX_NUM_PACKETS (ETH_TX_MIN_PACKET_SIZE + 20)
#define ETH_TX_NUM_PACKETS 20
 
//int response_time = 150000; // Response time before response packet it sent
// back (should be in nanoseconds).
644,7 → 641,7
unsigned long num_to_check;
for(num_to_check=ETH_TX_MIN_PACKET_SIZE;
num_to_check<ETH_TX_NUM_PACKETS;
num_to_check<ETH_TX_MIN_PACKET_SIZE + ETH_TX_NUM_PACKETS;
num_to_check++)
fill_and_tx_call_packet(num_to_check, response_time);
 
660,7 → 657,7
oeth_enable_rx();
 
for(num_to_check=ETH_TX_MIN_PACKET_SIZE;
num_to_check<ETH_TX_NUM_PACKETS;
num_to_check<ETH_TX_MIN_PACKET_SIZE + ETH_TX_NUM_PACKETS;
num_to_check++)
fill_and_tx_call_packet(num_to_check, response_time);
/tests/ethmac/sim/ethmac-rxtxoverflow.c
0,0 → 1,602
//////////////////////////////////////////////////////////////////////
//// ////
//// Interrupt-driven Ethernet MAC transmit test code ////
//// ////
//// Description ////
//// Attempt to overflow the RX path in MAC ////
//// ////
//// Author(s): ////
//// - jb, jb@orsoc.se, with parts taken from Linux kernel ////
//// open_eth driver. ////
//// ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
// Test sends the test code (0x1) for overflow test in first packet, which is
// read by Verilog stimulus module.
 
// SW is setup to echo back all packets it receives. TB sends 16 packets, as
// fast as possible, which should saturate the MAC's buffers.
// TB then waits for a BD to be ready and sends one more packet, and ensures
// that arrives in memory OK.
// Test is over when this software manages to send back 4 reply packets.
 
#include "cpu-utils.h"
#include "board.h"
#include "int.h"
#include "ethmac.h"
#include "eth-phy-mii.h"
 
volatile unsigned tx_done;
volatile unsigned rx_done;
static int next_tx_buf_num;
 
/* Functions in this file */
void ethmac_setup(void);
/* Interrupt functions */
void oeth_interrupt(void);
static void oeth_rx(void);
static void oeth_tx(void);
 
/* Let the ethernet packets use a space beginning here for buffering */
#define ETH_BUFF_BASE 0x01000000
 
 
#define RXBUFF_PREALLOC 1
#define TXBUFF_PREALLOC 1
//#undef RXBUFF_PREALLOC
//#undef TXBUFF_PREALLOC
 
/* The transmitter timeout
*/
#define TX_TIMEOUT (2*HZ)
 
/* Buffer number (must be 2^n)
*/
#define OETH_RXBD_NUM 16
#define OETH_TXBD_NUM 16
#define OETH_RXBD_NUM_MASK (OETH_RXBD_NUM-1)
#define OETH_TXBD_NUM_MASK (OETH_TXBD_NUM-1)
 
/* Buffer size
*/
#define OETH_RX_BUFF_SIZE 0x600-4
#define OETH_TX_BUFF_SIZE 0x600-4
 
/* Buffer size (if not XXBUF_PREALLOC
*/
#define MAX_FRAME_SIZE 1518
 
/* The buffer descriptors track the ring buffers.
*/
struct oeth_private {
//struct sk_buff* rx_skbuff[OETH_RXBD_NUM];
//struct sk_buff* tx_skbuff[OETH_TXBD_NUM];
 
unsigned short tx_next; /* Next buffer to be sent */
unsigned short tx_last; /* Next buffer to be checked if packet sent */
unsigned short tx_full; /* Buffer ring fuul indicator */
unsigned short rx_cur; /* Next buffer to be checked if packet
received */
oeth_regs *regs; /* Address of controller registers. */
oeth_bd *rx_bd_base; /* Address of Rx BDs. */
oeth_bd *tx_bd_base; /* Address of Tx BDs. */
// struct net_device_stats stats;
};
 
#define PHYNUM 7
 
void
eth_mii_write(char phynum, short regnum, short data)
{
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
regs->miiaddress = (regnum << 8) | phynum;
regs->miitx_data = data;
regs->miicommand = OETH_MIICOMMAND_WCTRLDATA;
regs->miicommand = 0;
while(regs->miistatus & OETH_MIISTATUS_BUSY);
}
 
short
eth_mii_read(char phynum, short regnum)
{
static volatile oeth_regs *regs = (oeth_regs *)(OETH_REG_BASE);
regs->miiaddress = (regnum << 8) | phynum;
regs->miicommand = OETH_MIICOMMAND_RSTAT;
regs->miicommand = 0;
while(regs->miistatus & OETH_MIISTATUS_BUSY);
return regs->miirx_data;
}
 
 
// Wait here until all packets have been transmitted
void
wait_until_all_tx_clear(void)
{
int i;
volatile oeth_bd *tx_bd;
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
 
int some_tx_waiting = 1;
while (some_tx_waiting)
{
some_tx_waiting = 0;
/* Go through the TX buffs, search for unused one */
for(i = 0; i < OETH_TXBD_NUM; i++) {
// Looking for buffer ready for transmit
if((tx_bd[i].len_status & OETH_TX_BD_READY))
some_tx_waiting = 1;
}
}
}
 
 
void
ethphy_set_10mbit(int phynum)
{
wait_until_all_tx_clear();
// Hardset PHY to just use 10Mbit mode
short cr = eth_mii_read(phynum, MII_BMCR);
cr &= ~BMCR_ANENABLE; // Clear auto negotiate bit
cr &= ~BMCR_SPEED100; // Clear fast eth. bit
eth_mii_write(phynum, MII_BMCR, cr);
}
 
 
void
ethphy_set_100mbit(int phynum)
{
wait_until_all_tx_clear();
// Hardset PHY to just use 100Mbit mode
short cr = eth_mii_read(phynum, MII_BMCR);
cr |= BMCR_ANENABLE; // Clear auto negotiate bit
cr |= BMCR_SPEED100; // Clear fast eth. bit
eth_mii_write(phynum, MII_BMCR, cr);
}
 
 
void
ethmac_setup(void)
{
// from arch/or32/drivers/open_eth.c
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
/* Reset MII mode module */
regs->miimoder = OETH_MIIMODER_RST; /* MII Reset ON */
regs->miimoder &= ~OETH_MIIMODER_RST; /* MII Reset OFF */
regs->miimoder = 0x64; /* Clock divider for MII Management interface */
/* Reset the controller.
*/
regs->moder = OETH_MODER_RST; /* Reset ON */
regs->moder &= ~OETH_MODER_RST; /* Reset OFF */
/* Setting TXBD base to OETH_TXBD_NUM.
*/
regs->tx_bd_num = OETH_TXBD_NUM;
/* Set min/max packet length
*/
regs->packet_len = 0x00400600;
/* Set IPGT register to recomended value
*/
regs->ipgt = 0x12;
/* Set IPGR1 register to recomended value
*/
regs->ipgr1 = 0x0000000c;
/* Set IPGR2 register to recomended value
*/
regs->ipgr2 = 0x00000012;
/* Set COLLCONF register to recomended value
*/
regs->collconf = 0x000f003f;
/* Set control module mode
*/
#if 0
regs->ctrlmoder = OETH_CTRLMODER_TXFLOW | OETH_CTRLMODER_RXFLOW;
#else
regs->ctrlmoder = 0;
#endif
/* Clear MIIM registers */
regs->miitx_data = 0;
regs->miiaddress = 0;
regs->miicommand = 0;
regs->mac_addr1 = ETH_MACADDR0 << 8 | ETH_MACADDR1;
regs->mac_addr0 = ETH_MACADDR2 << 24 | ETH_MACADDR3 << 16 | ETH_MACADDR4 << 8 | ETH_MACADDR5;
/* Clear all pending interrupts
*/
regs->int_src = 0xffffffff;
/* Promisc, IFG, CRCEn
*/
regs->moder |= OETH_MODER_PRO | OETH_MODER_PAD | OETH_MODER_IFG | OETH_MODER_CRCEN | OETH_MODER_FULLD;
/* Enable interrupt sources.
*/
 
regs->int_mask = OETH_INT_MASK_TXB |
OETH_INT_MASK_TXE |
OETH_INT_MASK_RXF |
OETH_INT_MASK_RXE |
OETH_INT_MASK_BUSY |
OETH_INT_MASK_TXC |
OETH_INT_MASK_RXC;
 
// Buffer setup stuff
volatile oeth_bd *tx_bd, *rx_bd;
int i,j,k;
/* Initialize TXBD pointer
*/
tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
/* Initialize RXBD pointer
*/
rx_bd = ((volatile oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
/* Preallocated ethernet buffer setup */
unsigned long mem_addr = ETH_BUFF_BASE; /* Defined at top */
 
// Setup TX Buffers
for(i = 0; i < OETH_TXBD_NUM; i++) {
//tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC | OETH_RX_BD_IRQ;
tx_bd[i].len_status = OETH_TX_BD_PAD | OETH_TX_BD_CRC;
tx_bd[i].addr = mem_addr;
mem_addr += OETH_TX_BUFF_SIZE;
}
tx_bd[OETH_TXBD_NUM - 1].len_status |= OETH_TX_BD_WRAP;
 
// Setup RX buffers
for(i = 0; i < OETH_RXBD_NUM; i++) {
rx_bd[i].len_status = OETH_RX_BD_EMPTY | OETH_RX_BD_IRQ; // Init. with IRQ
rx_bd[i].addr = mem_addr;
mem_addr += OETH_RX_BUFF_SIZE;
}
rx_bd[OETH_RXBD_NUM - 1].len_status |= OETH_RX_BD_WRAP; // Last buffer wraps
 
/* Enable RX and TX in MAC
*/
regs->moder &= ~(OETH_MODER_RXEN | OETH_MODER_TXEN);
regs->moder |= OETH_MODER_RXEN | OETH_MODER_TXEN;
 
next_tx_buf_num = 0; // init tx buffer pointer
 
return;
}
 
// Enable RX in ethernet MAC
void
oeth_enable_rx(void)
{
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
regs->moder |= OETH_MODER_RXEN;
}
 
// Disable RX in ethernet MAC
void
oeth_disable_rx(void)
{
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
regs->moder &= ~(OETH_MODER_RXEN);
}
 
 
/* Setup buffer descriptors with data */
/* length is in BYTES */
void tx_packet(void* data, int length)
{
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
volatile oeth_bd *tx_bd;
volatile int i;
 
tx_bd = (volatile oeth_bd *)OETH_BD_BASE;
tx_bd = (struct oeth_bd*) &tx_bd[next_tx_buf_num];
// If it's in use - wait
while ((tx_bd->len_status & OETH_TX_BD_IRQ));
 
/* Clear all of the status flags.
*/
tx_bd->len_status &= ~OETH_TX_BD_STATS;
/* If the frame is short, tell CPM to pad it.
*/
#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */
if (length <= ETH_ZLEN)
tx_bd->len_status |= OETH_TX_BD_PAD;
else
tx_bd->len_status &= ~OETH_TX_BD_PAD;
if ((int) data != 0){
//Copy the data into the transmit buffer, byte at a time
char* data_p = (char*) data;
char* data_b = (char*) tx_bd->addr;
for(i=0;i<length;i++)
{
data_b[i] = data_p[i];
}
}
 
/* Set the length of the packet's data in the buffer descriptor */
tx_bd->len_status = (tx_bd->len_status & 0x0000ffff) |
((length&0xffff) << 16);
 
/* Send it on its way. Tell controller its ready, interrupt when sent
* and to put the CRC on the end.
*/
tx_bd->len_status |= (OETH_TX_BD_READY | OETH_TX_BD_CRC | OETH_TX_BD_IRQ);
next_tx_buf_num = (next_tx_buf_num + 1) & OETH_TXBD_NUM_MASK;
tx_done++;
// This test over after 4 packets sent.
if (tx_done == 4)
{
report(0x8000000d);
exit(0);
}
 
return;
 
 
}
 
/* The interrupt handler.
*/
void
oeth_interrupt(void)
{
 
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
 
uint int_events;
int serviced;
serviced = 0;
/* Get the interrupt events that caused us to be here.
*/
int_events = regs->int_src;
regs->int_src = int_events;
 
/* Handle receive event in its own function.
*/
if (int_events & (OETH_INT_RXF | OETH_INT_RXE)) {
serviced |= 0x1;
oeth_rx();
}
 
/* Handle transmit event in its own function.
*/
if (int_events & (OETH_INT_TXB | OETH_INT_TXE)) {
serviced |= 0x2;
oeth_tx();
serviced |= 0x2;
}
 
/* Check for receive busy, i.e. packets coming but no place to
* put them.
*/
if (int_events & OETH_INT_BUSY) {
serviced |= 0x4;
if (!(int_events & (OETH_INT_RXF | OETH_INT_RXE)))
oeth_rx();
}
 
return;
}
 
 
 
static void
oeth_rx(void)
{
volatile oeth_regs *regs;
regs = (oeth_regs *)(OETH_REG_BASE);
 
volatile oeth_bd *rx_bdp;
int pkt_len, i;
int bad = 0;
rx_bdp = ((oeth_bd *)OETH_BD_BASE) + OETH_TXBD_NUM;
 
/* Find RX buffers marked as having received data */
for(i = 0; i < OETH_RXBD_NUM; i++)
{
bad=0;
if(!(rx_bdp[i].len_status & OETH_RX_BD_EMPTY)){ /* Looking for NOT empty buffers desc. */
/* Check status for errors.
*/
if (rx_bdp[i].len_status & (OETH_RX_BD_TOOLONG | OETH_RX_BD_SHORT)) {
bad = 1;
report(0xbaad0001);
}
if (rx_bdp[i].len_status & OETH_RX_BD_DRIBBLE) {
bad = 1;
report(0xbaad0002);
}
if (rx_bdp[i].len_status & OETH_RX_BD_CRCERR) {
bad = 1;
report(0xbaad0003);
}
if (rx_bdp[i].len_status & OETH_RX_BD_OVERRUN) {
bad = 1;
report(0xbaad0004);
}
if (rx_bdp[i].len_status & OETH_RX_BD_MISS) {
// not necessarily an issue
report(0xbaad0005);
}
if (rx_bdp[i].len_status & OETH_RX_BD_LATECOL) {
bad = 1;
report(0xbaad0006);
}
if (bad) {
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS;
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY;
exit(0xbaaaaaad);
continue;
}
else {
/* Process the incoming frame.
*/
pkt_len = rx_bdp[i].len_status >> 16;
 
// Attempt to transmit it back
tx_packet((void*)rx_bdp[i].addr,pkt_len);
/* finish up */
rx_bdp[i].len_status &= ~OETH_RX_BD_STATS; /* Clear stats */
rx_bdp[i].len_status |= OETH_RX_BD_EMPTY; /* Mark RX BD as empty */
rx_done++;
}
}
}
}
 
 
 
static void
oeth_tx(void)
{
volatile oeth_bd *tx_bd;
int i;
tx_bd = (volatile oeth_bd *)OETH_BD_BASE; /* Search from beginning*/
/* Go through the TX buffs, search for one that was just sent */
for(i = 0; i < OETH_TXBD_NUM; i++)
{
/* Looking for buffer NOT ready for transmit. and IRQ enabled */
if( (!(tx_bd[i].len_status & (OETH_TX_BD_READY))) && (tx_bd[i].len_status & (OETH_TX_BD_IRQ)) )
{
/* Single threaded so no chance we have detected a buffer that has had its IRQ bit set but not its BD_READ flag. Maybe this won't work in linux */
tx_bd[i].len_status &= ~OETH_TX_BD_IRQ;
 
/* Probably good to check for TX errors here */
/* set our test variable */
tx_done++;
// This test over after 4 packets sent.
if (tx_done == 4)
{
report(0x8000000d);
exit(0);
}
 
}
}
return;
}
 
// Send a packet, the very first byte of which will be read by the testbench
// and used to indicate which test we'll use.
static char cmd_tx_buffer[40];
void
send_ethmac_rxtx_test_init_packet(char test)
{
int i;
cmd_tx_buffer[0] = test;
// Clear rest of buffer
for(i=0;i<40;i++) cmd_tx_buffer[i] = test;
tx_packet(cmd_tx_buffer, 40); // Smallest packet that can be sent
}
 
// Loop to check if a number is prime by doing mod divide of the number
// to test by every number less than it
int
is_prime_number(unsigned long n)
{
unsigned long c;
if (n < 2) return 0;
for(c=2;c<n;c++)
if ((n % c) == 0)
return 0;
return 1;
}
 
 
int
main ()
{
/* Initialise handler vector */
int_init();
 
/* Install ethernet interrupt handler, it is enabled here too */
int_add(ETH0_IRQ, oeth_interrupt, 0);
 
/* Enable interrupts in supervisor register */
cpu_enable_user_interrupts();
 
/* Enable CPU timer */
cpu_enable_timer();
 
ethmac_setup(); /* Configure MAC, TX/RX BDs and enable RX and TX */
 
/* clear tx_done, the tx interrupt handler will set it when it's been
transmitted */
tx_done = 0;
rx_done = 0;
 
ethphy_set_100mbit(0);
send_ethmac_rxtx_test_init_packet(0x1); // 0x1 - overflow test
 
while(1); // Sit and wait for test to finish in interrupt-triggered code
}
/tests/or1200/sim/or1200-cy.S
102,7 → 102,7
 
.global _start
_start:
// Clear all regs
// Clear regs
l.movhi r1, 0
l.movhi r2, 0
l.movhi r3, 0
109,31 → 109,6
l.movhi r4, 0
l.movhi r5, 0
l.movhi r6, 0
l.movhi r7, 0
l.movhi r8, 0
l.movhi r9, 0
l.movhi r10, 0
l.movhi r11, 0
l.movhi r12, 0
l.movhi r13, 0
l.movhi r14, 0
l.movhi r15, 0
l.movhi r16, 0
l.movhi r17, 0
l.movhi r18, 0
l.movhi r19, 0
l.movhi r20, 0
l.movhi r21, 0
l.movhi r22, 0
l.movhi r23, 0
l.movhi r24, 0
l.movhi r25, 0
l.movhi r26, 0
l.movhi r27, 0
l.movhi r28, 0
l.movhi r29, 0
l.movhi r30, 0
l.movhi r31, 0
#ifdef OR1200_IMPL_CY
// Kick off test
149,16 → 124,16
 
 
#define CHECK_CY_CLEAR \
l.mfspr r20, r0, SPR_SR ; \
l.andi r21, r20, SPR_SR_CY ; \
l.sfne r21, r0 ; \
l.mfspr r6, r0, SPR_SR ; \
l.andi r6, r6, SPR_SR_CY ; \
l.sfne r6, r0 ; \
l.bf _fail ; \
l.nop
 
#define CHECK_CY_SET \
l.mfspr r20, r0, SPR_SR ; \
l.andi r21, r20, SPR_SR_CY ; \
l.sfnei r21, SPR_SR_CY ; \
l.mfspr r6, r0, SPR_SR ; \
l.andi r6, r6, SPR_SR_CY ; \
l.sfnei r6, SPR_SR_CY ; \
l.bf _fail ; \
l.nop
/tests/or1200/sim/or1200-basic.S
83,110 → 83,9
 
.global _start
_start:
 
/* Instruction cache enable */
/* Check if IC present and skip enabling otherwise */
l.mfspr r24,r0,SPR_UPR
l.andi r26,r24,SPR_UPR_ICP
l.sfeq r26,r0
l.bf .L8
l.jal _cache_init
l.nop
/* Disable IC */
l.mfspr r6,r0,SPR_SR
l.addi r5,r0,-1
l.xori r5,r5,SPR_SR_ICE
l.and r5,r6,r5
l.mtspr r0,r5,SPR_SR
/* Establish cache block size
If BS=0, 16;
If BS=1, 32;
r14 contain block size
*/
l.mfspr r24,r0,SPR_ICCFGR
l.andi r26,r24,SPR_ICCFGR_CBS
l.srli r28,r26,7
l.ori r30,r0,16
l.sll r14,r30,r28
/* Establish number of cache sets
r16 contains number of cache sets
r28 contains log(# of cache sets)
*/
l.andi r26,r24,SPR_ICCFGR_NCS
l.srli r28,r26,3
l.ori r30,r0,1
l.sll r16,r30,r28
/* Invalidate IC */
l.addi r6,r0,0
l.sll r5,r14,r28
.L7:
l.mtspr r0,r6,SPR_ICBIR
l.sfne r6,r5
l.bf .L7
l.add r6,r6,r14
/* Enable IC */
l.mfspr r6,r0,SPR_SR
l.ori r6,r6,SPR_SR_ICE
l.mtspr r0,r6,SPR_SR
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
 
.L8:
/* Data cache enable */
/* Check if DC present and skip enabling otherwise */
l.mfspr r24,r0,SPR_UPR
l.andi r26,r24,SPR_UPR_DCP
l.sfeq r26,r0
l.bf .L10
l.nop
/* Disable DC */
l.mfspr r6,r0,SPR_SR
l.addi r5,r0,-1
l.xori r5,r5,SPR_SR_DCE
l.and r5,r6,r5
l.mtspr r0,r5,SPR_SR
/* Establish cache block size
If BS=0, 16;
If BS=1, 32;
r14 contain block size
*/
l.mfspr r24,r0,SPR_DCCFGR
l.andi r26,r24,SPR_DCCFGR_CBS
l.srli r28,r26,7
l.ori r30,r0,16
l.sll r14,r30,r28
/* Establish number of cache sets
r16 contains number of cache sets
r28 contains log(# of cache sets)
*/
l.andi r26,r24,SPR_DCCFGR_NCS
l.srli r28,r26,3
l.ori r30,r0,1
l.sll r16,r30,r28
/* Invalidate DC */
l.addi r6,r0,0
l.sll r5,r14,r28
.L9:
l.mtspr r0,r6,SPR_DCBIR
l.sfne r6,r5
l.bf .L9
l.add r6,r6,r14
/* Enable DC */
l.mfspr r6,r0,SPR_SR
l.ori r6,r6,SPR_SR_DCE
l.mtspr r0,r6,SPR_SR
.L10:
// Kick off test
l.jal _main
l.nop
1100,4 → 999,5
l.nop 0x2
l.ori r3, r0, 0 /* Clear R3 */
l.nop 0x1 /* Exit simulation */
 
l.nop
l.nop
/tests/or1200/sim/or1200-intsyscall.S
8,9 → 8,9
Within the test we'll use following global variables:
 
r15 syscall interrupt counter
r16 syscall function counter
r17 irq interrupt counter
r18 intgen's base address
r6 syscall function counter
r10 irq interrupt counter
r12 intgen's base address
 
 
The test does the following:
77,15 → 77,15
.org 0x800
.global _user_irq_handler
_user_irq_handler:
l.addi r17, r17, 1
l.addi r10, r10, 1
/* Report values , 0x00000800 == user interrupt report*/
l.ori r3, r0, 0x0800
l.nop 2
l.or r3, r0, r17
l.or r3, r0, r10
l.nop 2
/* TODO - propably confirm it was intgen's IRQ that caused this */
/* Clear interrupt source */
l.ori r7, r18, 0x1 /* intgen IRQ clear address */
l.ori r7, r12, 0x1 /* intgen IRQ clear address */
l.sb 0(r7), r0 /* Any write clears the bit */
/* Clear OR1200 PICSR */
l.mfspr r7, r0, SPR_PICSR
107,7 → 107,7
l.xor r5, r5, r4
l.and r5, r7, r5 /* New SR without interrupt bits set */
l.mtspr r0, r5, SPR_ESR_BASE /* SR after l.rfe */
/* Report values , 0x00000c00 == tick timer report*/
/* Report values , 0x00000c00 == system call report*/
l.ori r3, r0, 0x0c00
l.nop 2
/* Get syscall number */
135,9 → 135,6
/* =================================================== [ main ] === */
.global _main
_main:
l.movhi r15, 0
l.movhi r16, 0
l.movhi r17, 0
#
# unmask (enable) all ints
151,13 → 148,18
l.ori r6,r6,SPR_SR_IEE
l.mtspr r0,r6,SPR_SR
 
l.movhi r15, 0
l.movhi r6, 0
l.movhi r10, 0
 
 
// Assumes r18 is intgen's base address
l.movhi r18,hi(INTGEN_BASE)
// Assumes r12 is intgen's base address
l.movhi r12,hi(INTGEN_BASE)
#define INTGEN_LOAD(x) \
l.ori r5,r0,lo(x) ;\
l.sb 0(r18),r5
l.sb 0(r12),r5
/* Test begin */
179,11 → 181,11
l.nop
l.ori r5,r0,1
l.sys 0x5
l.sb 0(r18),r5
l.sb 0(r12),r5
l.nop
l.nop
l.nop
l.sfnei r16, 0xf /* Should equal 15, 0xf */
l.sfnei r6, 0xf /* Should equal 15, 0xf */
l.bf _fail
l.nop
 
204,15 → 206,15
/* We'll restore them now */
l.mtspr r0, r7, SPR_ESR_BASE /* SR before syscall */
l.mtspr r0, r8, SPR_EPCR_BASE
l.add r16, r16, r3 /* Add syscall number to our counter */
l.add r6, r6, r3 /* Add syscall number to our counter */
l.movhi r4, hi(0x00400000) /* 4MB mark of memory */
/* Ensure memory access OK */
l.slli r3, r3, 2 /* Turn syscall number into a word address (<< 2) */
l.add r4, r4, r3 /* Access this offset from 4MB mark */
l.sw 0(r4), r16 /* Do a write to memory */
l.lwz r16, 0(r4) /* Do a read from memory */
l.sw 0(r4), r6 /* Do a write to memory */
l.lwz r6, 0(r4) /* Do a read from memory */
/* Report running value of syscall counter */
l.or r3, r0, r16
l.or r3, r0, r6
l.nop 2
l.rfe /* Now continue from where we had the l.sys */
/tests/or1200/sim/or1200-except.S
95,7 → 95,7
l.mfspr r3,r0,SPR_EEAR_BASE /* Get EEA */
l.nop 2
l.addi r11,r11,1 /* Increment 1st exception counter */
l.sfeqi r30, 0xd /* Is this a data bus test, if so return with l.rfe */
l.sfeqi r2, 0xd /* Is this a data bus test, if so return with l.rfe */
l.bf 1f
l.movhi r5, 0 /* r5 should be the one causing the error on dbus */
/* Instruction bus error test return */
138,27 → 138,32
.global _dtlb_handler
/* Exception handler - DMMU TLB miss */
/* Assume 64-entry TLB cache */
_dtlb_handler:
l.mfspr r20, r0, SPR_EEAR_BASE
_dtlb_handler:
l.sw -4(r1),r4
l.sw -8(r1),r5
l.sw -12(r1),r6
l.sw -16(r1),r7
l.sw -20(r1),r8
l.mfspr r2, r0, SPR_EEAR_BASE
/* Find the entry/set for this address */
l.srli r21, r20, 13 /* r21 = VPN, shift by size 8192 = 2**13 */
l.andi r22, r21, 0x3f /* 64 entries = 6 bit mask, r22 = set number */
l.srli r13, r2, 13 /* r13 = VPN, shift by size 8192 = 2**13 */
l.andi r4, r13, 0x3f /* 64 entries = 6 bit mask, r4 = set number */
/* If page is in the 0xc0000000 space we map to 16MB part of
memory, ie 0x0 => 0x01000000, otherwise 1-1 mapping */
l.movhi r23, hi(0xc0000000)
l.ori r23, r23, lo(0xc0000000)
l.srli r23, r23, 13 /* Get page address, shift by page size, 13 bits */
l.movhi r24, hi(0xff << 11) /* Mask for top byte of VPN */
l.ori r24, r24, lo(0xff << 11)
l.and r24, r24, r21 /* Mask in only top byte of VPN */
l.sfeq r23, r24 /* Decide if it's in our special mapped region or not*/
l.movhi r5, hi(0xc0000000)
l.ori r5, r5, lo(0xc0000000)
l.srli r5, r5, 13 /* Get page address, shift by page size, 13 bits */
l.movhi r6, hi(0xff << 11) /* Mask for top byte of VPN */
l.ori r6, r6, lo(0xff << 11)
l.and r6, r6, r13 /* Mask in only top byte of VPN */
l.sfeq r5, r6 /* Decide if it's in our special mapped region or not*/
/* First, Setup value for DTLBM (match) reg, is same for both cases */
l.movhi r24, hi(SPR_ITLBMR_VPN) /* VPN mask into r24 */
l.ori r24, r24, lo(SPR_ITLBMR_VPN)
l.and r25, r20, r24 /* AND address with VPN mask */
l.ori r25, r25, SPR_DTLBMR_V /* OR in valid bit */
l.mtspr r22, r25, SPR_DTLBMR_BASE(0) /* Write to DTLBR register */
l.movhi r6, hi(SPR_ITLBMR_VPN) /* VPN mask into r6 */
l.ori r6, r6, lo(SPR_ITLBMR_VPN)
l.and r7, r2, r6 /* AND address with VPN mask */
l.ori r7, r7, SPR_DTLBMR_V /* OR in valid bit */
l.mtspr r4, r7, SPR_DTLBMR_BASE(0) /* Write to DTLBR register */
 
l.bf _highmem_map
l.nop
166,31 → 171,35
_lomem_map:
/* Do 1:1 mapping for this request */
/* Setup value for translate register */
l.movhi r24, hi(SPR_ITLBTR_PPN) /* PPN mask into r24 */
l.ori r24, r24, lo(SPR_ITLBTR_PPN)
l.and r25, r20, r24 /* AND address with PPN mask */
l.ori r25, r25, DTLB_PR_NOLIMIT /* Set all execute enables, no lims. */
l.mtspr r22, r25, SPR_DTLBTR_BASE(0) /* Write to DTLTR register */
l.movhi r6, hi(SPR_ITLBTR_PPN) /* PPN mask into r6 */
l.ori r6, r6, lo(SPR_ITLBTR_PPN)
l.and r7, r2, r6 /* AND address with PPN mask */
l.ori r7, r7, DTLB_PR_NOLIMIT /* Set all execute enables, no lims. */
l.mtspr r4, r7, SPR_DTLBTR_BASE(0) /* Write to DTLTR register */
l.j _dtlb_done
l.addi r18, r18, 1 /* Incremement low-mapping counter */
l.addi r14, r14, 1 /* Incremement low-mapping counter */
 
_highmem_map:
/* Do top byte, 0xc0->0x01, mapping for this request */
/* Setup value for translate register */
l.movhi r24, hi(SPR_ITLBTR_PPN) /* PPN mask into r24 */
l.ori r24, r24, lo(SPR_ITLBTR_PPN)
l.and r25, r20, r24 /* AND address with PPN mask */
l.movhi r26, hi(0xff000000) /* Top byte address mask */
l.or r25, r26, r25 /* Set top byte to 0xff */
l.xor r25, r26, r25 /* Now clear top byte with XOR */
l.movhi r26, hi(0x01000000) /* Top address byte */
l.or r25, r26, r25 /* Set top address byte */
l.ori r25, r25, DTLB_PR_NOLIMIT /* Set all execute enables, no lims. */
l.mtspr r22, r25, SPR_DTLBTR_BASE(0) /* Write to DTLTR register */
l.addi r19, r19, 1 /* Incremement low-mapping counter */
l.movhi r6, hi(SPR_ITLBTR_PPN) /* PPN mask into r6 */
l.ori r6, r6, lo(SPR_ITLBTR_PPN)
l.and r7, r2, r6 /* AND address with PPN mask */
l.movhi r8, hi(0xff000000) /* Top byte address mask */
l.or r7, r8, r7 /* Set top byte to 0xff */
l.xor r7, r8, r7 /* Now clear top byte with XOR */
l.movhi r8, hi(0x01000000) /* Top address byte */
l.or r7, r8, r7 /* Set top address byte */
l.ori r7, r7, DTLB_PR_NOLIMIT /* Set all execute enables, no lims. */
l.mtspr r4, r7, SPR_DTLBTR_BASE(0) /* Write to DTLTR register */
l.addi r15, r15, 1 /* Incremement low-mapping counter */
_dtlb_done:
l.lwz r4,-4(r1)
l.lwz r5,-8(r1)
l.lwz r6,-12(r1)
l.lwz r7,-16(r1)
l.lwz r8,-20(r1)
l.rfe
 
 
202,110 → 211,8
 
.global _start
_start:
 
/* Instruction cache enable */
/* Check if IC present and skip enabling otherwise */
l.mfspr r24,r0,SPR_UPR
l.andi r26,r24,SPR_UPR_ICP
l.sfeq r26,r0
l.bf .L8
l.jal _cache_init
l.nop
/* Disable IC */
l.mfspr r6,r0,SPR_SR
l.addi r5,r0,-1
l.xori r5,r5,SPR_SR_ICE
l.and r5,r6,r5
l.mtspr r0,r5,SPR_SR
/* Establish cache block size
If BS=0, 16;
If BS=1, 32;
r14 contain block size
*/
l.mfspr r24,r0,SPR_ICCFGR
l.andi r26,r24,SPR_ICCFGR_CBS
l.srli r28,r26,7
l.ori r30,r0,16
l.sll r14,r30,r28
/* Establish number of cache sets
r16 contains number of cache sets
r28 contains log(# of cache sets)
*/
l.andi r26,r24,SPR_ICCFGR_NCS
l.srli r28,r26,3
l.ori r30,r0,1
l.sll r16,r30,r28
/* Invalidate IC */
l.addi r6,r0,0
l.sll r5,r14,r28
.L7:
l.mtspr r0,r6,SPR_ICBIR
l.sfne r6,r5
l.bf .L7
l.add r6,r6,r14
/* Enable IC */
l.mfspr r6,r0,SPR_SR
l.ori r6,r6,SPR_SR_ICE
l.mtspr r0,r6,SPR_SR
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
 
.L8:
/* Data cache enable */
/* Check if DC present and skip enabling otherwise */
l.mfspr r24,r0,SPR_UPR
l.andi r26,r24,SPR_UPR_DCP
l.sfeq r26,r0
l.bf .L10
l.nop
/* Disable DC */
l.mfspr r6,r0,SPR_SR
l.addi r5,r0,-1
l.xori r5,r5,SPR_SR_DCE
l.and r5,r6,r5
l.mtspr r0,r5,SPR_SR
/* Establish cache block size
If BS=0, 16;
If BS=1, 32;
r14 contain block size
*/
l.mfspr r24,r0,SPR_DCCFGR
l.andi r26,r24,SPR_DCCFGR_CBS
l.srli r28,r26,7
l.ori r30,r0,16
l.sll r14,r30,r28
/* Establish number of cache sets
r16 contains number of cache sets
r28 contains log(# of cache sets)
*/
l.andi r26,r24,SPR_DCCFGR_NCS
l.srli r28,r26,3
l.ori r30,r0,1
l.sll r16,r30,r28
/* Invalidate DC */
l.addi r6,r0,0
l.sll r5,r14,r28
.L9:
l.mtspr r0,r6,SPR_DCBIR
l.sfne r6,r5
l.bf .L9
l.add r6,r6,r14
/* Enable DC */
l.mfspr r6,r0,SPR_SR
l.ori r6,r6,SPR_SR_DCE
l.mtspr r0,r6,SPR_SR
.L10:
// Kick off test
l.jal _main
l.nop
323,8 → 230,8
l.addi r11,r0,0 /* exception counter 1 */
l.addi r12,r0,0 /* exception counter 2 */
l.addi r13,r0,0
l.addi r18,r0,0 /* DMMU exception counter for low mem mapping */
l.addi r19,r0,0 /* DMMU exception counter for hi mem mapping */
l.addi r14,r0,0 /* DMMU exception counter for low mem mapping */
l.addi r15,r0,0 /* DMMU exception counter for hi mem mapping */
l.sw 0x0(r0),r0 /* Initialize RAM */
l.sw 0x4(r0),r0 /* Initialize RAM */
l.sw 0x8(r0),r0 /* Initialize RAM */
553,7 → 460,7
l.nop
l.movhi r12, 0 /* Reset exception counters */
l.movhi r11, 0
l.ori r30, r0, 0xd /* put 0xd in r30, indicate it's databus test */
l.ori r2, r0, 0xd /* put 0xd in r2, indicate it's databus test */
/* Cause access error */
/* Load word */
l.movhi r5, 0xee00 /* Address to cause an error */
636,7 → 543,7
/* TODO: do this it with cache enabled/disabled */
l.movhi r12, 0 /* Reset exception counters */
l.movhi r11, 0
l.movhi r30, 0x0 /* put 0x0 in r30,indicate it's instruction bus test*/
l.movhi r2, 0x0 /* put 0x0 in r2,indicate it's instruction bus test*/
/* Cause access error */
l.movhi r5, 0xee00 /* Address to cause an error */
l.jalr r5 /* Jump and link to bad address */
673,10 → 580,10
l.movhi r7, hi(0xaabbccdd)
l.ori r7, r7, lo(0xaabbccdd)
l.sw 0(r5), r7 /* Shouldn't trigger MMU */
l.sfne r18, r0
l.sfne r14, r0
l.bf _dmmu_test_error
l.nop
l.sfne r19, r0
l.sfne r15, r0
l.bf _dmmu_test_error
l.nop
692,10 → 599,10
l.sfne r7, r8
l.bf _dmmu_test_error
l.nop
l.sfnei r18, 0x1 /* Check for lo mem mapping */
l.sfnei r14, 0x1 /* Check for lo mem mapping */
l.bf _dmmu_test_error
l.nop
l.sfne r19, r0 /* hi-mem counter should still be 0 */
l.sfne r15, r0 /* hi-mem counter should still be 0 */
l.bf _dmmu_test_error
l.nop
 
706,10 → 613,10
l.sfne r7, r8
l.bf _dmmu_test_error
l.nop
l.sfnei r18, 0x1 /* Check for lo mem mapping */
l.sfnei r14, 0x1 /* Check for lo mem mapping */
l.bf _dmmu_test_error
l.nop
l.sfnei r19, 0x1 /* hi-mem counter should still be 0 */
l.sfnei r15, 0x1 /* hi-mem counter should still be 0 */
l.bf _dmmu_test_error
l.nop
 
719,10 → 626,10
l.sfne r7, r8
l.bf _dmmu_test_error
l.nop
l.sfnei r18, 0x2 /* Check for lo mem mapping increment */
l.sfnei r14, 0x2 /* Check for lo mem mapping increment */
l.bf _dmmu_test_error
l.nop
l.sfnei r19, 0x1 /* hi-mem counter should still be 1 */
l.sfnei r15, 0x1 /* hi-mem counter should still be 1 */
l.bf _dmmu_test_error
l.nop
 
729,10 → 636,10
l.addi r7, r7, 0x1111 /* Incremement value we're writing */
l.sw 4(r6), r7 /* Should cause DMMU miss, himem */
l.sfnei r18, 0x2 /* Check for lo mem mapping */
l.sfnei r14, 0x2 /* Check for lo mem mapping */
l.bf _dmmu_test_error
l.nop
l.sfnei r19, 0x2 /* hi-mem counter should be 2 */
l.sfnei r15, 0x2 /* hi-mem counter should be 2 */
l.bf _dmmu_test_error
l.nop
 
741,10 → 648,10
l.sfne r7, r8
l.bf _dmmu_test_error
l.nop
l.sfnei r18, 0x3 /* Check for lo mem mapping increment */
l.sfnei r14, 0x3 /* Check for lo mem mapping increment */
l.bf _dmmu_test_error
l.nop
l.sfnei r19, 0x2 /* hi-mem counter should still be 2 */
l.sfnei r15, 0x2 /* hi-mem counter should still be 2 */
l.bf _dmmu_test_error
l.nop
 
777,10 → 684,10
l.sfne r7, r8
l.bf _dmmu_test_error
l.nop
l.sfnei r18, 0xb /* Check for lo mem mapping increment to 11 */
l.sfnei r14, 0xb /* Check for lo mem mapping increment to 11 */
l.bf _dmmu_test_error
l.nop
l.sfnei r19, 0xa /* hi-mem counter should be 10 */
l.sfnei r15, 0xa /* hi-mem counter should be 10 */
l.bf _dmmu_test_error
l.nop
/Makefile.inc
29,8 → 29,6
#### ####
######################################################################
 
DESIGN_NAME ?=orpsoc
 
OR32_TOOL_PREFIX=or32-elf-
 
OR32_LD=$(OR32_TOOL_PREFIX)ld
46,11 → 44,17
# Special case for CPU drivers
CPU_DRIVER ?=$(SW_ROOT)/drivers/or1200
 
# If BOARD_PATH is set, we'll first scan that path for which drivers they have
DESIGN_NAME ?=orpsoc
 
# If BOARD is set, we'll first scan that path for which drivers they have
# and will override any locally named driver directories here.
ifdef BOARD
BOARD_PATH=$(SW_ROOT)/../boards/$(BOARD)
#$(info BOARD is being used: $(BOARD_PATH))
 
ifeq ($(V), 1)
$(info BOARD is set to : $(BOARD_PATH))
endif
 
BOARD_SPECIFIC_DRIVERS=$(shell if [ -e \
$(BOARD_PATH)/sw/drivers ]; then \
ls $(BOARD_PATH)/sw/drivers; \
58,6 → 62,12
BOARD_SW_TESTS=$(shell if [ -e $(BOARD_PATH)/sw/tests ]; then\
ls $(BOARD_PATH)/sw/tests; \
fi)
 
# Set RTL_VERILOG_INCLUDE_DIR
RTL_VERILOG_INCLUDE_DIR=$(BOARD_PATH)/rtl/verilog/include
#We don't actually want this
#DESIGN_NAME ?=$(strip $(shell echo $(BOARD)| cut -d '/' -f 2))
 
endif
 
COMMON_SW_DRIVERS=$(shell ls $(SW_ROOT)/drivers )
199,10 → 209,10
%.elf: %.S $(ELF_DEPENDS) $(SUPPORT_LIBS)
$(Q)$(OR32_CC) $< $(ELF_DEPENDS) $(OR32_CFLAGS) $(OR32_LDFLAGS) -o $@
 
%.o: %.S
%.o: %.S processed-verilog-headers
$(Q)$(OR32_CC) $(OR32_CFLAGS) -c $< -o $@
 
%.o: %.c
%.o: %.c processed-verilog-headers
$(Q)$(OR32_CC) $(OR32_CFLAGS) -c $< -o $@
 
COMPILE_SRCS_BASENAMES=$(basename $(COMPILE_SRCS))
213,11 → 223,11
 
# Rule to make all necessary driver objects
 
$(ORPSOC_LIB): $(PROCESSED_DEFINES)
$(ORPSOC_LIB):
$(Q)echo; echo "\t### Building software support library ###"; echo
$(Q)$(MAKE) -C $(SW_ROOT)/lib liborpsoc.a
 
$(VECTORS_OBJ):
$(VECTORS_OBJ):
$(Q)$(MAKE) -C $(CPU_DRIVER) crt0.o
 
 
/drivers/ethmac/include/ethmac.h
64,7 → 64,11
uint mac_addr0; /* MAC Individual Address Register 0 */
uint mac_addr1; /* MAC Individual Address Register 1 */
uint hash_addr0; /* Hash Register 0 */
uint hash_addr1; /* Hash Register 1 */
uint hash_addr1; /* Hash Register 1 */
uint txctrl; /* Transmit control frame Register */
uint rxctrl; /* Rx control frame Register */
uint wbdbg; /* Wishbone state machine debug information */
 
} oeth_regs;
 
/* Ethernet buffer descriptor */
/drivers/or1200/cache.S
0,0 → 1,114
#include "spr-defs.h"
/* Cache init. To be called during init ONLY */
.global _cache_init
.type _cache_init,@function
 
_cache_init:
/* Instruction cache enable */
/* Check if IC present and skip enabling otherwise */
l.mfspr r3,r0,SPR_UPR
l.andi r4,r3,SPR_UPR_ICP
l.sfeq r4,r0
l.bf .L8
l.nop
/* Disable IC */
l.mfspr r6,r0,SPR_SR
l.addi r5,r0,-1
l.xori r5,r5,SPR_SR_ICE
l.and r5,r6,r5
l.mtspr r0,r5,SPR_SR
/* Establish cache block size
If BS=0, 16;
If BS=1, 32;
r14 contain block size
*/
l.mfspr r3,r0,SPR_ICCFGR
l.andi r4,r3,SPR_ICCFGR_CBS
l.srli r5,r4,7
l.ori r6,r0,16
l.sll r14,r6,r5
/* Establish number of cache sets
r7 contains number of cache sets
r5 contains log(# of cache sets)
*/
l.andi r4,r3,SPR_ICCFGR_NCS
l.srli r5,r4,3
l.ori r6,r0,1
l.sll r7,r6,r5
/* Invalidate IC */
l.addi r6,r0,0
l.sll r5,r14,r5
.L7:
l.mtspr r0,r6,SPR_ICBIR
l.sfne r6,r5
l.bf .L7
l.add r6,r6,r14
/* Enable IC */
l.mfspr r6,r0,SPR_SR
l.ori r6,r6,SPR_SR_ICE
l.mtspr r0,r6,SPR_SR
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
 
.L8:
/* Data cache enable */
/* Check if DC present and skip enabling otherwise */
l.mfspr r3,r0,SPR_UPR
l.andi r4,r3,SPR_UPR_DCP
l.sfeq r4,r0
l.bf .L10
l.nop
/* Disable DC */
l.mfspr r6,r0,SPR_SR
l.addi r5,r0,-1
l.xori r5,r5,SPR_SR_DCE
l.and r5,r6,r5
l.mtspr r0,r5,SPR_SR
/* Establish cache block size
If BS=0, 16;
If BS=1, 32;
r14 contain block size
*/
l.mfspr r3,r0,SPR_DCCFGR
l.andi r4,r3,SPR_DCCFGR_CBS
l.srli r5,r4,7
l.ori r6,r0,16
l.sll r14,r6,r5
/* Establish number of cache sets
r7 contains number of cache sets
r5 contains log(# of cache sets)
*/
l.andi r4,r3,SPR_DCCFGR_NCS
l.srli r5,r4,3
l.ori r6,r0,1
l.sll r7,r6,r5
/* Invalidate DC */
l.addi r6,r0,0
l.sll r5,r14,r5
.L9:
l.mtspr r0,r6,SPR_DCBIR
l.sfne r6,r5
l.bf .L9
l.add r6,r6,r14
/* Enable DC */
l.mfspr r6,r0,SPR_SR
l.ori r6,r6,SPR_SR_DCE
l.mtspr r0,r6,SPR_SR
 
.L10:
/* Return */
l.jr r9
l.nop
/drivers/or1200/crt0.S
65,6 → 65,7
l.movhi r29, 0
l.movhi r30, 0
l.movhi r31, 0
 
/* Clear status register, set supervisor mode */
l.ori r1, r0, SPR_SR_SM
l.mtspr r0, r1, SPR_SR
196,125 → 197,18
 
ENTRY(_start)
 
/* Instruction cache enable */
/* Check if IC present and skip enabling otherwise */
l.mfspr r24,r0,SPR_UPR
l.andi r26,r24,SPR_UPR_ICP
l.sfeq r26,r0
l.bf .L8
/* Cache initialisation */
l.jal _cache_init
l.nop
/* Disable IC */
l.mfspr r6,r0,SPR_SR
l.addi r5,r0,-1
l.xori r5,r5,SPR_SR_ICE
l.and r5,r6,r5
l.mtspr r0,r5,SPR_SR
/* Establish cache block size
If BS=0, 16;
If BS=1, 32;
r14 contain block size
*/
l.mfspr r24,r0,SPR_ICCFGR
l.andi r26,r24,SPR_ICCFGR_CBS
l.srli r28,r26,7
l.ori r30,r0,16
l.sll r14,r30,r28
/* Establish number of cache sets
r16 contains number of cache sets
r28 contains log(# of cache sets)
*/
l.andi r26,r24,SPR_ICCFGR_NCS
l.srli r28,r26,3
l.ori r30,r0,1
l.sll r16,r30,r28
/* Invalidate IC */
l.addi r6,r0,0
l.sll r5,r14,r28
.L7:
l.mtspr r0,r6,SPR_ICBIR
l.sfne r6,r5
l.bf .L7
l.add r6,r6,r14
/* Enable IC */
l.mfspr r6,r0,SPR_SR
l.ori r6,r6,SPR_SR_ICE
l.mtspr r0,r6,SPR_SR
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
l.nop
 
.L8:
/* Data cache enable */
/* Check if DC present and skip enabling otherwise */
l.mfspr r24,r0,SPR_UPR
l.andi r26,r24,SPR_UPR_DCP
l.sfeq r26,r0
l.bf .L10
l.nop
/* Disable DC */
l.mfspr r6,r0,SPR_SR
l.addi r5,r0,-1
l.xori r5,r5,SPR_SR_DCE
l.and r5,r6,r5
l.mtspr r0,r5,SPR_SR
/* Establish cache block size
If BS=0, 16;
If BS=1, 32;
r14 contain block size
*/
l.mfspr r24,r0,SPR_DCCFGR
l.andi r26,r24,SPR_DCCFGR_CBS
l.srli r28,r26,7
l.ori r30,r0,16
l.sll r14,r30,r28
/* Establish number of cache sets
r16 contains number of cache sets
r28 contains log(# of cache sets)
*/
l.andi r26,r24,SPR_DCCFGR_NCS
l.srli r28,r26,3
l.ori r30,r0,1
l.sll r16,r30,r28
/* Invalidate DC */
l.addi r6,r0,0
l.sll r5,r14,r28
.L9:
l.mtspr r0,r6,SPR_DCBIR
l.sfne r6,r5
l.bf .L9
l.add r6,r6,r14
/* Enable DC */
l.mfspr r6,r0,SPR_SR
l.ori r6,r6,SPR_SR_DCE
l.mtspr r0,r6,SPR_SR
 
.L10:
 
/* Clear BSS */
LOAD_SYMBOL_2_GPR(r28, _bss_start)
LOAD_SYMBOL_2_GPR(r30, _bss_end)
LOAD_SYMBOL_2_GPR(r5, _bss_start)
LOAD_SYMBOL_2_GPR(r6, _bss_end)
1:
l.sw (0)(r28), r0
l.sfltu r28, r30
l.sw (0)(r5), r0
l.sfltu r5, r6
l.bf 1b
l.addi r28, r28, 4
 
/* Initialise UART in a C function */
/*l.jal _uart_init
l.nop*/
l.addi r5, r5, 4
/* Jump to main program entry point (argc = argv = 0) */
CLEAR_GPR(r3)
360,7 → 254,7
l.sw 0x70(r1), r30
l.sw 0x74(r1), r31
l.sw 0x78(r1), r32
 
l.jal default_exception_handler_c
l.nop
/drivers/or1200/int.c
25,37 → 25,37
}
 
/* Add interrupt handler */
int int_add(unsigned long vect, void (* handler)(void *), void *arg)
int int_add(unsigned long irq, void (* handler)(void *), void *arg)
{
if(vect >= MAX_INT_HANDLERS)
if(irq >= MAX_INT_HANDLERS)
return -1;
 
int_handlers[vect].handler = handler;
int_handlers[vect].arg = arg;
int_handlers[irq].handler = handler;
int_handlers[irq].arg = arg;
 
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << vect));
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << irq));
return 0;
}
 
/* Disable interrupt */
int int_disable(unsigned long vect)
int int_disable(unsigned long irq)
{
if(vect >= MAX_INT_HANDLERS)
if(irq >= MAX_INT_HANDLERS)
return -1;
mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(0x00000001L << vect));
mtspr(SPR_PICMR, mfspr(SPR_PICMR) & ~(0x00000001L << irq));
return 0;
}
 
/* Enable interrupt */
int int_enable(unsigned long vect)
int int_enable(unsigned long irq)
{
if(vect >= MAX_INT_HANDLERS)
if(irq >= MAX_INT_HANDLERS)
return -1;
 
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << vect));
mtspr(SPR_PICMR, mfspr(SPR_PICMR) | (0x00000001L << irq));
return 0;
}
71,7 → 71,12
while(i < 32) {
if((picsr & (0x01L << i)) && (int_handlers[i].handler != 0)) {
(*int_handlers[i].handler)(int_handlers[i].arg);
mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(0x00000001L << i));
#ifdef OR1200_INT_CHECK_BIT_CLEARED
// Ensure PICSR bit is cleared, incase it takes some time for the
// IRQ line going low to propagate back to PIC
while (mfspr(SPR_PICSR) & (0x00000001L << i))
#endif
mtspr(SPR_PICSR, mfspr(SPR_PICSR) & ~(0x00000001L << i));
}
i++;
}
/drivers/or1200/link.ld
72,14 → 72,10
/* ensure there is enough room for stack */
.stack (NOLOAD): {
. = ALIGN(4);
sstack = . ;
_sstack = . ;
. = . + _min_stack ;
. = . + _min_stack ;
. = ALIGN(4);
stack = . ;
_stack = . ;
estack = . ;
_estack = . ;
} > ram
.stab 0 (NOLOAD) :
/drivers/or1200/Makefile
1,7 → 1,7
SW_ROOT=../..
 
# Sources to go into the liborpsoc.a support library
COMPILE_SRCS=exceptions.c int.c or1200-mmu.S or1200-utils.c
COMPILE_SRCS=exceptions.c int.c or1200-mmu.S or1200-utils.c cache.S
 
include $(SW_ROOT)/Makefile.inc
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.