📄 skyeye硬件模拟平台,第三部分 硬件仿真实现之四.htm
字号:
0-1所示:</P>
<P><A name=IDA4SKTB><B>图 0-1 8019AS模拟结构图</B></A><BR><IMG height=318
alt="图 0-1 8019AS模拟结构图"
src="SkyEye硬件模拟平台,第三部分 硬件仿真实现之四.files/image001.gif" width=450 border=0
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P><A name=IDALTKTB><SPAN class=atitle3>3.
虚拟8019AS网络芯片的内存结构</SPAN></A><BR>SkyEye模拟的虚拟8019AS网络芯片工作在8位模式下,网络芯片含有8K字节的RAM,地址为0x4000-0x5fff(指的是网络芯片上的存储地址,而不是ISA总线的地址,是网络芯片工作用的存储器),每256个字节称为一页,共有64页。页的地址就是地址的高8位,页地址为0x00--0xff
。</P>
<P>首先看一下0x40-0x5f页,这8k的ram的一部分用来存放接收的数据包,一部分用来存储待发送的数据包,具体由驱动编写者自己决定。(一般发包只要能容纳一个最大的以太网包就可以了,所以定义为0x40-0x45页,即0x4000-0x45ff,约1.5k。剩下的都用来收包)。按照8019AS硬件规范手册上的规定,8位工作模式下只能使用4000-5fff,16位模式才能用到6000-7fff的RAM,所以我们还是以手册为准。</P>
<P><A name=IDATTKTB><B>图 0-2 NE2K兼容网络芯片的RAM空间结构</B></A><BR><IMG height=259
alt="图 0-2 NE2K兼容网络芯片的RAM空间结构"
src="SkyEye硬件模拟平台,第三部分 硬件仿真实现之四.files/image003.jpg" width=291 border=0
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>再看一下第0页,也就是图 0
6中的PROM,PROM的内容是网络芯片在上电复位的时候从93C46里读出来的,其中0x00-0x0B(工作于8位DMA模式)用于存放本节点MAC地址,奇偶地址内容是重复放置的。如:MAC地址00
00 12 34 56 78存放在0x00-0x0B中为00 00 00 00 12 12 34 34 56 56 78
78,单地址和双地址的内容是重复的,一般使用偶数地址的内容,这主要是为了同时适应8位和16位的DMA。8019芯片外接一块93c46
eeprom,上电时自动从93c46里把MAC地址读入到PROM中,所以为虚拟网络芯片写驱动,只要在init函数中读PROM中的MAC地址,并写入工作寄存器PAR0-PAR5就可以了。网络芯片工作时的地址判断依据就是这几个寄存器,与PROM及93c46无关。PROM的其它地址不能使用。值得一提的是,虽然一般来说mac地址随便取一个就可以了,但要注意其最高字节不能是奇数,否则就是一个multicast
mac地址,以后的应用中会有问题。</P>
<P>根据以上的分析,虚拟8019AS网络芯片要模拟的网络芯片内部RAM共两块:</P>
<P>0x0000-0x000B,12字节,页号为0x00。存放MAC地址</P>
<P>0x4000-0x5FFF,8192字节,页号为0x40-0x60(只用到0x5f,0x60为结束边界),用于存放收发的数据包缓冲,具体收发多少由驱动程序初始化决定。</P>
<P>以上两块内存都是网络芯片的内部数据,不在系统的地址空间内,实际上SkyEye模拟的CPU是看不到这两块内存的,只能通过读写寄存器间接访问。</P>
<P><A name=IDAFUKTB><SPAN class=atitle3>4.
虚拟8019AS网络芯片的寄存器结构</SPAN></A><BR>在RTL8019AS或其它NE2k兼容的网络芯片中,软件对网络芯片内存的读写是通过一个数据寄存器(地址偏移0x10)进行的,方式是DMA,DMA的长度、起始地址等由控制寄存器决定。而DMA又分为Remote
DMA和Local DMA,首先解释一下这两种DMA:</P>
<TABLE width=400 border=0>
<TBODY>
<TR>
<TD width=200>Local DMA<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">以太网<IMG
height=12 alt="" src="SkyEye硬件模拟平台,第三部分 硬件仿真实现之四.files/image005.gif"
width=88 border=0
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">网络芯片 RAM</TD>
<TD>Remote DMA<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">网络芯片 RAM<IMG
height=12 alt="" src="SkyEye硬件模拟平台,第三部分 硬件仿真实现之四.files/image005.gif"
width=88 border=0
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">host主机</TD></TR></TBODY></TABLE>
<P>Local DMA是网络芯片自动收发数据到/从网络芯片的RAM,而Remote
DMA是CPU主动从网络芯片的RAM读写数据到/从CPU的RAM。具体的读写其实可以分为三种:</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>CPU读/写数据到网络芯片<BR>控制方式是设置如下控制寄存器,它们分别为:
<UL>
<LI>RBCR0,RBCR1:存放要读写数据的长度
<LI>RSAR0,RSAR1:存放数据在网络芯片RAM中存放的起始地址(而不是页号,但通常还是以某页的00为起始,如0x4000)
<LI>CR:向命令寄存器发出Remote DMA开始指令</LI></UL><BR>然后就可以通过数据寄存器去读写数据了,宽度为8位。
<LI>网络芯片发数据到以太网<BR>CPU把数据用Remote DMA 发到网络芯片后,就可以让网络芯片用Local
DMA向外发数据了。<BR>需要设置如下的控制寄存器,它们分别为:<BR>
<UL>
<LI>TPSR :网络芯片要发送的数据在网络芯片RAM中的起始页号。所以发送的数据只能从某页的开头存放。
<LI>TBCR0,TBCR1:要发送的数据总长度
<LI>CR:向命令寄存器发出发送数据包的指令CMD_XMIT。</LI></UL><BR>然后程序就可以返回了,网络芯片会自动用Local
DMA发送数据包。
<LI>网络芯片从以太网读数据<BR>网络芯片在从以太网读取数据过程中,会用到的寄存器如下:<BR>
<UL>
<LI>PSTART,PSTOP:网络芯片接收数据缓冲区的起始和终止页号。形成一个接收缓冲环。每页256字节
<LI>CURR:接收缓冲环写页指针,初始化=PSTART
<LI>BNRY:接收缓冲环读页指针,初始化=PSTART</LI></UL></LI></UL>
<P>这四个寄存器在init函数里初始化,以后有数据包到来时,网络芯片自动判断是否发给本机,是则用Local
DMA存入数据,并自动修改读写指针。</P>
<P><A name=IDAKWKTB><B>图 0-3 与DMA有关的寄存器</B></A><BR><IMG height=191
alt="图 0-3 与DMA有关的寄存器" src="SkyEye硬件模拟平台,第三部分 硬件仿真实现之四.files/image007.jpg"
width=642 border=0
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>8019AS的寄存器地址为0x00-0x1f,有page 0-3共4页,每页都以0x00-0x0f访问,但实际访问的是不同的寄存器。page
3里的寄存器属于8019专用,不是NE2K标准,并且不常用,所以不模拟了。我们的寄存器共3页,页号为0-2。此外还有两个寄存器,不属于任何页:</P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>0x10为DMA读写地址,CPU和网络芯片交换数据通过此地址
<LI>0x1F为Reset地址,向该地址写或读任何数都引起网络芯片复位,一般在初始化时将网络芯片复位一次,注意复位后要等待几十ms再进行下一步操作。</LI></UL>
<P><A name=IDA2WKTB><B>表 0 1 8019AS寄存器</B></A><BR><IMG height=340
alt="表 0 1 8019AS寄存器" src="SkyEye硬件模拟平台,第三部分 硬件仿真实现之四.files/image009.jpg"
width=553 border=0
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
<P>下面分别叙述虚拟8019AS网络芯片所模拟的各页中寄存器,如表 0
1所示。每个寄存器的各个bit位的具体含义可参考8019AS硬件规范手册,下面写出各寄存器的页内偏移地址,以及编写驱动时读写的常用值表示什么意思,有助于理解。每个寄存器的各种写入值可以以"或"的关系运算后写入,R表示只读,W表示只写,R/W表示可以读也可以写:</P>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">PAGE 0</B></P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>CR控制命令寄存器:0x00,R/W。CR中各个bit位的含意如下: <BR>CMD_STOP 0x01
网络芯片停止收发数据<BR>CMD_RUN 0x02 网络芯片执行命令并开始收发数据包(命令为下面四种)<BR>CMD_XMIT 0x04
Local DMA SEND(网络芯片――>以太网 )<BR>CMD_READ 0x08 Remote DMA
READ,用于手动接收数据(网络芯片―>CPU)<BR>CMD_WRITE 0x10 Remote DMA WRITE
(网络芯片<――CPU)<BR>CMD_SEND 0x18 Send命令,
用于自动接收数据包(网络芯片――>CPU)<BR>CMD_NODMA 0x20 停止DMA操作<BR>CMD_PAGE0 0x00
选择第0页(要先选页,再读写该页寄存器)<BR>CMD_PAGE1 0x40 选择第1页<BR>CMD_PAGE2 0x80 选择第2页
<LI>PSTART:0x01,W,接收缓冲环起始页<BR>RECV_START 0x4600 接收缓冲起始地址(写入时要右移8位得到页号)
<LI>PSTOP:0x02,W,接收缓冲环终止页(不包括此页)<BR>RECV_STOP 0x6000
接收缓冲结束地址(写入时要右移8位得到页号)
<LI>BNRY,0x03,R/W,接收缓冲环读指针<BR>硬件初始化时,PSTART =CURR,以后用CMD_SEND
命令自动收数据包,网络芯片会自动调整这个寄存器的值。若接收出错,会重新调整成CURR的值。
<LI>TPSR,0x04,W,Local DMA发送缓冲起始页寄存器。<BR>XMIT_START 0x4000
发送缓冲起始地址(写入时要右移8位得到页号)
<LI>TBCR0,0x05,W,Local DMA发送长度低位。
<LI>TBCR1,0x06,W,Local
DMA发送长度高位。<BR>上述两个寄存器是网络芯片外发数据包的长度,执行发送命令前根据实际长度设置。
<LI>ISR,0x07,R/W,中断状态寄存器,各个bit位的含意如下: <BR>ISR_PRX 0x01
正确接收数据包中断。做接收处理<BR>ISR_PTX 0x02 正确发送数据包中断。做不做处理要看上层软件了。<BR>ISR_RXE 0x04
接收数据包出错。做重新设置BNRY=CURR处理。 <BR>ISR_TXE 0x08
由于冲突次数过多,发送出错。做重发处理<BR>ISR_OVW 0x10 网络芯片内存溢出。做软件重启网络芯片处理。见手册。<BR>ISR_CNT
0x20 出错计数器中断,屏蔽掉(屏蔽用IMR寄存器)。<BR>ISR_RDC 0x40 Remote DMA结束
。屏蔽掉。轮询等待DMA结束。<BR>ISR_RST 0x80
网络芯片Reset,屏蔽掉。<BR><BR>在中断处理程序中读出ISR寄存器的值,分别与以上各值"与",若结果为1则表示发生了该种中断,需要处理,处理完毕向ISR寄存器写入该值(即将该中断位置1)即可清除该中断。<BR>比如:if
(isr & ISR_PRX) {<BR> 处理收到的数据包;<BR> IOWRITE(R_ISR,ISR_PRX);
清除正确接收数据包中断 <BR> };
<LI>RSAR0,0x08,W,Remote DMA目的起始地址低位<BR>XMIT_START 0x4000 取其低位
<LI>RSAR1,0x09,W,Remote DMA目的起始地址高位<BR>XMIT_START 0x4000 取其高位
<LI>RBCR0,0x0A,W,Remote DMA数据长度低位
<LI>RBCR1,0x0B,W,Remote
DMA数据长度高位<BR>上述两个寄存器是CPU向网络芯片写入或读出数据包的实际长度,执行Remote DMA命令前需要设置这两个寄存器。
<LI>RCR,0x0C,W,接收配置寄存器,<BR>初始化时写入0x04,表示只接收发给本网络芯片MAC地址的、大于64字节的以太网包或广播包。
<LI>TCR,0x0D,W,发送配置寄存器<BR>初始化开始时写入0x02,表示置网络芯片为Loop
Back模式,停止发送数据包,初始化结束写入0x00。正常发送数据包并加上CRC。
<LI>DCR,0x0E,W,数据配置寄存器<BR>初始化时写入0x48,表示8位模式,FIFO深度8字节,DMA方式。
<LI>IMR,0x0F,W,中断屏蔽寄存器<BR>它的各位和ISR中的各位相对应,向IMR写入以下各值即为打开相应中断,<BR>ISR_PRX
0x01<BR>ISR_PTX 0x02<BR>ISR_RXE 0x04<BR>ISR_TXE 0x08<BR>ISR_OVW
0x10<BR>ISR_CNT 0x20<BR>ISR_RDC 0x40<BR>ISR_RST 0x80<BR>如IOWRITE(R_IMR,
ISR_OVW | ISR_PRX )表示打开溢出和接收中断,其它中断都屏蔽。</LI></UL>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">PAGE
1:</B></P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>CR:0x00,R/W,含意与PAGE0的CR含意相同
<LI>PAR0,0x01,R/W,网络芯片MAC地址最高位
<LI>PAR1,0x02,R/W,网络芯片MAC地址
<LI>PAR2,0x03,R/W,网络芯片MAC地址
<LI>PAR3,0x04,R/W,网络芯片MAC地址
<LI>PAR4,0x05,R/W,网络芯片MAC地址
<LI>PAR5,0x06,R/W,网络芯片MAC地址最低位<BR>如网络芯片的MAC地址为:00:01:02:03:04:05,则PARi=0x0i。初始化时网络芯片会从PROM读出MAC地址并写入这六个寄存器。
<LI>CURR,0x07,R/W,接收缓冲环写指针,
指向下一个包到来时的起始页。<BR>硬件初始化时,CURR=BNRY=PSTART,以后由网络芯片自动负责更新。<BR>PAGE1中,偏移量0x08到0x0F这8个寄存器是组播地址寄存器,它们决定了网络芯片对组播数据包的收发,暂时不模拟这8个寄存器。</LI></UL>
<P><B xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">PAGE
2:</B></P>
<UL xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<LI>CR,0x00,R/W,含意与PAGE0的CR含意相同
<LI>PSTART,0x01,R,用来读PSTART状态
<LI>PSTOP,0x02, R,用来读PSTOP状态
<LI>TPSR,0x04, R,用来读TPSR状态
<LI>RCR,0x0C, R,用来读接收配置寄存器RCR状态
<LI>TCR,0x0D, R,用来读发送配置寄存器TCR状态
<LI>DCR,0x0E, R,用来读数据配置寄存器DCR状态
<LI>IMR,0x0F, R,用来读中断屏蔽寄存器IMR状态</LI></UL>
<P>这页的寄存器大部分是只读的,可读出相关的配置信息等。</P>
<P><A name=IDAG2PTB><SPAN class=atitle3>5.
虚拟网络芯片接收数据包的方法</SPAN></A><BR>在前面CR寄存器的说明中可以看到,普通的RTL8019从网络芯片RAM读数据到CPU有两种方式:</P>
<P>1. 目前SkyEye虚拟网络芯片还不支持Remote DMA READ方式:<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">硬件初始化时,BNRY读指针 =
CURR写指针-1 =PSTART。<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">有数据包要读时,操作步骤如下:</P>
<P>a.查看bnry是否=CURR-1,不等则说明有数据包要读<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">b.用bnry初始化DMA起址控制器RSAR0,1<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">c
用18初始化DMA长度控制器RBCR0,1<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">d.执行Remote DMA
READ命令<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">e.读出以太网包头(18字节),从包头中读出包长度<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">f.同b-e读出所有数据<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">g.调整bnry指针=CURR-1<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">这期间如果bnry指到了缓冲环的尾部还要手工调整它回到环的开头。</P>
<P>2.虚拟8019网络芯片支持更快更简单的SEND COMMAND方式,读数据包的步骤如下:<BR
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">硬件初始化时,BNRY = CURR =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -