📄 rtl8019as_net420.cpp
字号:
#include "rtl8019as_net.h"
#include "iostream"
//for wpcap
#include <stdlib.h>
#include <stdio.h>
#include <pcap.h>
#define LINE_LEN 16
//end
Core::s32 tuntap_fd;
#define DE_BUG
//#ifdef DE_BUG
//#define DBG_PRINT(a...) fprintf(stderr, ##a)
//#else
//#define DBG_PRINT(a...)
//#endif
#ifdef DE_BUG
#define WUKONG_STDOUT(x) do { std::cout<<x<<std::endl;} while(0)
#else
#define WUKONG_STDOUT(x)
#endif
namespace DEVICE
{
nic8019::nic8019()
{
rtl8019_reset();
}
void nic8019::rtl8019_reset()
{
rtl8019_net.par[0] = 0;
rtl8019_net.par[1] = 0x01;
rtl8019_net.par[2] = 0x02;
rtl8019_net.par[3] = 0x03;
rtl8019_net.par[4] = 0x04;
rtl8019_net.par[5] = 0x05;
//DBG_PRINT("++++reset+++++\n");
//结束或完成DMA
rtl8019_net.cr = 0x21;
//PSTART,PSTOP:网络芯片接收数据缓冲区的起始和终止页号。形成一个接收缓冲环。
//没页256字节
//CURR:接收缓冲环写页指针,初始化=PSTART
//BNRY:接收缓冲环读页执政,初始化=PSTART
rtl8019_net.bnry = 0x0;
rtl8019_net.curr = 0x0;
rtl8019_net.pstart = 0x0;
rtl8019_net.pstop = 0x0;
// TPSR:网络芯片要发送的数据在网络芯片RAM中的其实页号 ,
//TBCR0,1要发送数据的长度
//CR:向控制寄存器发CR_TXP,即开始传输数据
rtl8019_net.tpsr = 0x0;//0x40
rtl8019_net.tbcr0 = 0;
rtl8019_net.tbcr1 = 0;
//RBCR0,1 读写数据长度 RSAR0,1 网络芯片中的起始地址
//CR:发出开始读/写命令 CR_REMOTE_R CR_REMOTE_W
rtl8019_net.rbcr0 = 0;
rtl8019_net.rbcr1 = 0;
rtl8019_net.rsar0 = 0;
rtl8019_net.rsar1 = 0;
//配置寄存器
rtl8019_net.rcr = 0x0;//这些数值跟驱动程序有关,但模拟网卡用这些值的话将打打增加复杂度和工作量
rtl8019_net.tcr = 0x00;
rtl8019_net.dcr = 0x48;//FIFO的选择,普通模式接收,字节传输,看spec需要进一步改进
rtl8019_net.imr = 0xff;//全部开放中断 rtl8019_net.isr = 0x40;//无远程DMA,可能要置0
nic_state = 0; //无中断
}
Core::s8 nic8019::rtl8019_read(Core::u32 addr)
{
/*DBG_PRINT("++++++rtl8019_read address is : %h++++++\n",addr);*/
Core::s32 ret_value;
ret_value = -1;
if( (rtl8019_net.cr & CR_PAGE_NUM) == CR_PAGE_ZERO )
{
// page 0 :读寄存器,只模拟了部分的寄存器
//DBG_PRINT("Page 0 hasn't been simulated.\n");
//return -1;
switch( addr)
{
case CR_ADDRESS:
ret_value = rtl8019_net.cr;
break;
case ISR_ADDRESS:
ret_value = rtl8019_net.isr; //DBG_PRINT("rtl8019_net.isr=0x%x\n",ret_value); //DBG_PRINT("+++++++++++++++rtl8019_net.isr=0x%x\n\n",rtl8019_net.isr);
break;
case BNRY_ADDRESS:
ret_value = rtl8019_net.bnry; //DBG_PRINT("rtl8019_net.bnry=0x%x\n",ret_value);
break;
case DATA_ADDRESS://从网卡读取数据到虚拟机
ret_value = read_from_rtl8019( );
break;
default:
//attention 在驱动222行有错误,想reset端口读数据
//WUKONG_STDOUT("The register you want in Page 0 can't read, address:0x"<<std::hex<<addr);
return -1;
break;
}
}
else if( (rtl8019_net.cr & CR_PAGE_NUM) == CR_PAGE_ONE)
{// 读取 page1的寄存器
switch(addr)
{
case CR_ADDRESS:
ret_value = rtl8019_net.cr;
break;
case PAR0_ADDRESS:case PAR1_ADDRESS: case PAR2_ADDRESS:
case PAR3_ADDRESS:case PAR4_ADDRESS: case PAR5_ADDRESS:
ret_value = rtl8019_net.par[ ((addr & 0x000000ff)>>2) -1];
/*DBG_PRINT("address is:%x data is:%x\n",(addr & 0x000000ff)>>2,ret_value);*/
/* DBG_PRINT("0%x 1%x 2%x 3%x 4%x 5%x\n",rtl8019_net.par[0],rtl8019_net.par[1],rtl8019_net.par[2],rtl8019_net.par[3],rtl8019_net.par[4],rtl8019_net.par[5]);*/
break;
case CURR_ADDRESS:
ret_value = rtl8019_net.curr; //DBG_PRINT("rtl8019_net.curr=0x%x\n",ret_value);
break;
case MAR0_ADDRESS:case MAR1_ADDRESS: case MAR2_ADDRESS:case MAR3_ADDRESS:
case MAR4_ADDRESS:case MAR5_ADDRESS: case MAR6_ADDRESS:case MAR7_ADDRESS:
ret_value = rtl8019_net.mar[((addr & 0x000000ff) - 0x20)>>2] ;
break;
case DATA_ADDRESS://从芯片到虚拟机
ret_value = read_from_rtl8019( );
break;
default:
WUKONG_STDOUT("Error address,in rtl8019_read,page1.address: 0x"<<std::hex<<addr);
break;
}
}
else if ((rtl8019_net.cr & CR_PAGE_NUM) == CR_PAGE_TWO)
{//读取 page 2 的寄存器
switch( addr)
{
case CR_ADDRESS:
ret_value = rtl8019_net.cr;
break;
case PSTART_ADDRESS:
ret_value = rtl8019_net.pstart;
break;
case PSTOP_ADDRESS:
ret_value = rtl8019_net.pstop;
break;
case TPSR_ADDRESS:
ret_value = rtl8019_net.tpsr; break;
case RCR_ADDRESS:
ret_value = rtl8019_net.rcr;
break;
case TCR_ADDRESS:
ret_value = rtl8019_net.tcr;
break;
case DCR_ADDRESS:
ret_value = rtl8019_net.dcr;
break;
case IMR_ADDRESS:
ret_value = rtl8019_net.imr; //DBG_PRINT("rtl8019_net.imr=0x%x\n",ret_value);
break; case DATA_ADDRESS://从芯片到虚拟机
ret_value = read_from_rtl8019( );
break;
default:
WUKONG_STDOUT("Error address,in rtl8019_read,page2.address: 0x"\
<<std::hex<<addr<<"cr is: 0x"<<rtl8019_net.cr);
ret_value = -1;
break;
}
}
else if ((rtl8019_net.cr & CR_PAGE_NUM) == CR_PAGE_THREE)
{
//读取page 3 的寄存器
WUKONG_STDOUT("Page 3 hasn't been simulated.\n");
ret_value = -1;
}
/*DBG_PRINT("++++++rtl8019_read address is : 0x%x data is: 0x%x++++++\n",addr,ret_value);*/
return ret_value;
}
Core::s8 nic8019::rtl8019_write(Core::u32 addr, Core::s8 data)
{
/* Core::s32 ret_value;*/
/*ret_value = 1;*/
/*printf("++++++rtl8019_write address is : %x,data:%x++++++\n",addr,data);*/
if( (rtl8019_net.cr & CR_PAGE_NUM) == CR_PAGE_ZERO )
{
//page 0 可写寄存器(部分)
switch( addr )
{
case CR_ADDRESS:
/*rtl8019_net.cr = (u8)data;*/
write_cr(data);
break;
case PSTART_ADDRESS :
rtl8019_net.pstart = data;
break;
case PSTOP_ADDRESS:
rtl8019_net.pstop = data;
break;
case BNRY_ADDRESS:
rtl8019_net.bnry = data;
break;
case TPSR_ADDRESS:
rtl8019_net.tpsr = data;
break;
case TBCR0_ADDRESS:
rtl8019_net.tbcr0 = data;
break;
case TBCR1_ADDRESS:
rtl8019_net.tbcr1 = data;
break; case ISR_ADDRESS:
rtl8019_net.isr = data; if(data ==0 ) nic_state = 0; if ( rtl8019_net.isr == (Core::u8)0xff){rtl8019_net.isr = 0x40;} printf("write......rtl8019_net.isr=0x%x\n",data);//attetion
break; case RSAR0_ADDRESS:
rtl8019_net.rsar0 = data;
break; case RSAR1_ADDRESS:
rtl8019_net.rsar1 = data;
break; case RBCR0_ADDRESS :
rtl8019_net.rbcr0 = data;
break; case RBCR1_ADDRESS :
rtl8019_net.rbcr1 = data;
break;
case RCR_ADDRESS:
rtl8019_net.rcr = data;
break;
case TCR_ADDRESS:
rtl8019_net.tcr = data;
break;
case DCR_ADDRESS:
rtl8019_net.dcr = data;
break;
case IMR_ADDRESS:
rtl8019_net.imr = data; rtl8019_net.imr |= IMR_RDC;//because of the nic driver attention printf("+++++++++++++++write......rtl8019_net.imr=0x%x\n",rtl8019_net.imr);
break; case DATA_ADDRESS://从虚拟机到网络芯片
write_to_rtl8019(data);
break;
case RESET_ADDRESS:
rtl8019_reset();
break;
default:
WUKONG_STDOUT("Error address,in rtl8019_write, page 0.address: 0x"<<std::hex<<addr);
return -1;
break;
}
}
else if( (rtl8019_net.cr & CR_PAGE_NUM) == CR_PAGE_ONE)
{
// page 1 可写寄存器
switch(addr) {
case CR_ADDRESS:
/*rtl8019_net.cr = data;*/
write_cr(data );
break;
case PAR0_ADDRESS:case PAR1_ADDRESS: case PAR2_ADDRESS:
case PAR3_ADDRESS:case PAR4_ADDRESS: case PAR5_ADDRESS:
rtl8019_net.par[ ((addr && 0x000000ff)>>2) -1] = data ;
break;
case CURR_ADDRESS:
rtl8019_net.curr = data;
break;
case MAR0_ADDRESS:case MAR1_ADDRESS: case MAR2_ADDRESS:case MAR3_ADDRESS:
case MAR4_ADDRESS:case MAR5_ADDRESS: case MAR6_ADDRESS:case MAR7_ADDRESS:
rtl8019_net.mar[((addr && 0x000000ff)>>2) -1] =data;
break;
case RESET_ADDRESS:
rtl8019_reset();
break;
case DATA_ADDRESS://从虚拟机到网络芯片
write_to_rtl8019(data);
break;
default:
WUKONG_STDOUT("Error address,in rtl8019_write, page 1.address: 0x"<<std::hex<<addr); return -1;
break;
}
}
else if ((rtl8019_net.cr & CR_PAGE_NUM) == CR_PAGE_TWO)
{
/*page 2 read only*/
/*DBG_PRINT("rtl8019as page 2 register is read only. address: 0x%x cr is: 0x%x\n", addr,rtl8019_net.cr);*/ switch( addr ) {
case CR_ADDRESS:
/*rtl8019_net.cr = (u8)data;*/
write_cr(data );
break;
case DATA_ADDRESS://虚拟机到网络芯片
write_to_rtl8019(data);
break; default: WUKONG_STDOUT("The register you want to write in page 2 is read only.\ address: 0x"<<std::hex<<addr<<"cr is: 0x"<<std::hex<<rtl8019_net.cr); return -1; break; }
}
else if ((rtl8019_net.cr & CR_PAGE_NUM) == CR_PAGE_THREE)
{
//page 3 ,8019特有,没有模拟
WUKONG_STDOUT("Page 3 hasn't been simulated.");
return -1;
} /* if( (addr == ISR_ADDRESS) || (addr==IMR_ADDRESS) ) { } */ return 1;
}
void nic8019::write_cr(Core::s8 data)
{
if( (rtl8019_net.cr&CR_START) == CR_START)
{//清除网卡中断
rtl8019_net.isr &= ~(ISR_RST);
}
//DBG_PRINT("+++++++++++++++++++++WRITE_CR\n");
rtl8019_net.cr = data;//
if( ((rtl8019_net.cr & CR_SEND) == CR_SEND) && !(rtl8019_net.cr&CR_FINISH))
{// 把数据从网络芯片读到虚拟机
// DBG_PRINT("+++++++++++++++++++++CR_SEND\n");
if(rtl8019_net.rbcr1 == 0x0f)//硬件规定(CR_SEND特有),由驱动写入
{
rtl8019_net.rsar0 = 0;
rtl8019_net.rsar1 = rtl8019_net.bnry;
start_page = rtl8019_net.bnry - 0x40;
//attention 这里可能有错,需要进一步的验证
read_total_count = rtl8019_net.nic_ram[start_page*PAGE_SIZE+2]+\
rtl8019_net.nic_ram[start_page*PAGE_SIZE+3]+4;//4 is 8019as header size
rtl8019_net.rbcr0 = (Core::u8)(read_total_count&0x0ff);//注意是网络序 big-endian
rtl8019_net.rbcr1 = (Core::u8)(read_total_count>>8)&0xff;
read_total_page = (read_total_count + PAGE_SIZE-1)>>8;//一共要读取几页
read_offset = 0; page_to_read = 0;
} WUKONG_STDOUT("+++++++write_cr.CR_SEND, start_page:0x"\ <<std::hex<<start_page<<"read_total_count:0x"<<std::hex<<read_total_count); WUKONG_STDOUT("+++++++write_cr.CR_SEND,read_total_page:0x"\ <<std::hex<<read_total_page); return;// attention please!!,maybe wrong
}
if( ((rtl8019_net.cr & CR_REMOTE_W) == CR_REMOTE_W) && !(rtl8019_net.cr&CR_FINISH))
{ //从虚拟机到网络芯片
start_page = rtl8019_net.rsar1;
write_total_count = rtl8019_net.rbcr0 + (((Core::s32)rtl8019_net.rbcr1)<<8); WUKONG_STDOUT("write_cr.CR_REMOTE_W,start_page:0x"<<std::hex<<start_page\
<<"\twrite_total_count:0x"<<std::hex<<write_total_count);
printf("\n");
if( write_total_count> (6*PAGE_SIZE))
{
WUKONG_STDOUT("In write_cr,写入的数据个数大于缓冲区");
}
write_offset = 0; return;// attention please!!,maybe wrong
}
if( (rtl8019_net.cr & CR_TXP) == CR_TXP)
{//从网络芯片写入以太网
rtl8019_net.tpsr = rtl8019_net.rsar1;//高8位起始地址正好是页号
rtl8019_net.tbcr0 = rtl8019_net.rbcr0;
rtl8019_net.tbcr1 = rtl8019_net.rbcr1;
printf("write_cr,tpsr:0x%x write_total_count:0x%x",rtl8019_net.tpsr,\ write_total_count);
//must be deleted under windows
tuntap_output( );
rtl8019_net.isr = ISR_PTX;
if( (rtl8019_net.imr&IMR_PTX) == IMR_PTX)
{//机器中断由board设置,attention
nic_state |= 1;
//state->io.intsr |= NETCARDINT;
// armulator_update_int( );
}
}
}
static Core::s32 read_after_receive=1;
Core::s8 nic8019::read_from_rtl8019()
{
//DBG_PRINT("read_from_rtl8019 hasn't been completed!\n");
// return -1;
Core::s32 data;
//DBG_PRINT("read_from_rtl8019 hasn't been completed!\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -