⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtl8019as_net420.cpp

📁 浙江大学的悟空嵌入式系统模拟器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#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 + -