本文分析VC709板卡自带的TRD程序中对应JAVA GUI界面的start和stop按钮对应的startTest和stopTest功能。
当选择performance mode的时候,GUI进入的界面可以设置四个DMA engine的包大小和选择对应的模式:
performance: loopback,pktchk,pktgen;
performance+raw_ethernet: loopback;
然后点击start,则App程序开始发包,点stop则程序App程序停止发包。
下面具体分析点击start和stop时,GUI程序给xdma驱动发送了什么命令,对FPGA进行了怎么样的配置。
首先明确一点,startTest只用对TX engine进行配置,对应的RX Engine是不用配置的。
软件准备testCmd
当软件设置好testmode后,调用StartTest(int statsfd, int engine, int testmode, int maxSize);
第一个参数是xdma_stat的文件描述符,第二个参数为TX engine的编号(0,1,2,3),第三参数为上面设好的tmode,第四个参数为最大的包大小;
- 其中第三个参数testmode可取的值为下面宏的组合:
1
2
3
4
5
6
7
8int testmode可取下面的值:
- ENABLE_LOOPBACK 只有loopback
- ENABLE_PKTCHK 只是硬件check
- ENABLE_PKTGEN 只是硬件generate
- ENABLE_PKTCHK|ENABLE_PKTGEN 硬件既check又generate
在StartTest函数中,根据第2,3,4 号参数初始化testCmd(TestCmd类型),
testCmd.Engine = engine;
testCmd.TestMode = testmode;
testCmd.MaxPktSize = maxSize;
并且最后testCmd.TestMode |= TEST_START,表示是start test;
如果是Raw_ETH的performance,还要testCmd.TestMode |= ENABLE_CRISCROSS;
最后将testCmd传给xdma的ioctl();
总结 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15testCmd.TestMode
loopback check generate check|generate
init: 0x0000 0200 0x0000 0100 0x0000 0400 0x0000 0500
Not Raw_ETH: 0x0000 8200 0x0000 8100 0x0000 8400 0x0000 8500
Raw_ETH: 0x0000 A200 0x0000 A100 0x0000 A400 0x0000 A500
//即32位的寄存
0000 0000 0000 0000 0000 0000 0000 0000 (从右往左第0位开始)
//第8位:check位
//第9位:loopback位
//第10位:gen位
//第14位:inprocess位
//第15位:startTest位:1表示start,0 表示stop
//第13位:criscross位,即raw_eth performance位
xdma驱动的ioctl()接收到命令
然后看到xdma驱动的ioctl()函数:
在ISTART_TEST和ISTOP_TEST的case分支时,
用传入的testCmd赋值ustate,然后调用(uptr->UserSetState)(eptr, &ustate, uptr->privData);
这个函数才是真正的置寄存器函数。
sgusr.c中的mySetState
我们看来sgusr.c中的mySetState
其中要判断engien是否为TX engine ==> if (privdata == 0x54545454);(说明了start test只用设置TX engine)
然后RawTestMode = ustate->TestMode;
然后根据RawTestMOde来初始化testmode = 0;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31if (RawTestMode & TEST_START) //见下面的解释,给testmode置值
{
testmode = 0;
if (RawTestMode & ENABLE_LOOPBACK)
testmode |= LOOPBACK;
if (RawTestMode & ENABLE_PKTCHK)
testmode |= PKTCHKR;
if (RawTestMode & ENABLE_PKTGEN)
testmode |= PKTGENR;
}
else //TEST_STOP时,将之前in process的testmode的对应位置0,如果是loopback模式,则第1位置0;如果是CHK或者GEN,则第0位置0
{
if (RawTestMode & ENABLE_PKTCHK)
testmode &= ~PKTCHKR;
if (RawTestMode & ENABLE_PKTGEN)
testmode &= ~PKTGENR;
if (RawTestMode & ENABLE_LOOPBACK)
testmode &= ~LOOPBACK;
}
/* Test start / stop conditions */
所以
loopback check generate check|generate
TEST_START testmode 0x0000 0002 0x0000 0001 0x0000 0001 0x0000 0001
Important
然后开始写寄存器,即配置FPGA以改变功能
sgusr.c文件中,有一个条件编译#ifdef RAW_ETH,根据没有定义RAW_ETH会执行不同的代码,从而设置不同的寄存器值,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46//TEST_START时:
//not Raw_ETH: ndef RAW_ETH
XIo_Out32 (TXbarbase + DESIGN_MODE_ADDRESS,PERF_DESIGN_MODE);
(TXbarbase + 0x9004, 0x0000 0003)
XIo_Out32 (TXbarbase + PKT_SIZE_ADDRESS, val);
(TXbarbase + 0x9104/0x9204/0x9304/0x9404, maxpaketSize)
XIo_Out32 (TXbarbase + SEQNO_WRAP_REG , seqno);
(TXbarbase + 0x9110/0x9210/0x9310/0x9410, 512)
//然后重置CONFIG_ADDRESS
XIo_Out32 (TXbarbase + TX_CONFIG_ADDRESS, 0);
(TXbarbase + 0x9108/0x9208/0x9308/0x9408, 0)
//如果是PKTCHK|LOOPBACK:
if (RawTestMode & (ENABLE_PKTCHK | ENABLE_LOOPBACK))
XIo_Out32 (TXbarbase + TX_CONFIG_ADDRESS, testmode);
(TXbarbase + 0x9108/0x9208/0x9308/0x9408, 0x00000001|0x00000002)
if (RawTestMode & ENABLE_PKTGEN)
XIo_Out32 (TXbarbase + RX_CONFIG_ADDRESS, testmode);
(TXbarbase + 0x9100/0x9200/0x9300/0x9400, 0x00000001)
//Raw_ETH:
XIo_Out32 (TXbarbase + PKT_SIZE_ADDRESS, val);
(TXbarbase + 0x9104/0x9204/0x9304/0x9404, maxpaketSize)
//然后重置CONFIG_ADDRESS
XIo_Out32 (TXbarbase + TX_CONFIG_ADDRESS, 0);
(TXbarbase + 0x9108/0x9208/0x9308/0x9408, 0)
//如果是PKTCHK|LOOPBACK:
if (RawTestMode & (ENABLE_PKTCHK | ENABLE_LOOPBACK))
XIo_Out32 (TXbarbase + TX_CONFIG_ADDRESS, testmode);
(TXbarbase + 0x9108/0x9208/0x9308/0x9408, 0x00000001|0x00000002)
XIo_Out32 (TXbarbase + DESIGN_MODE_ADDRESS,PERF_DESIGN_MODE);
(TXbarbase + 0x9004, 0x0000 0000)注意这个非Raw_ETH的值不同
if(RawTestMode & ENABLE_CRISCROSS):
XIo_Out32(TXbarbase+NW_PATH_OFFSET_OTHER+XXGE_RCW1_OFFSET, 0x50000000);
else:
XIo_Out32(TXbarbase+NW_PATH_OFFSET+XXGE_RCW1_OFFSET, 0x50000000);
XIo_Out32(TXbarbase+NW_PATH_OFFSET+XXGE_TC_OFFSET, 0x50000000);
//如果是PKEGEN:
if (RawTestMode & ENABLE_PKTGEN)
XIo_Out32 (TXbarbase + RX_CONFIG_ADDRESS, testmode);
(TXbarbase + 0x9100/0x9200/0x9300/0x9400, 0x00000001)
//TEST_STOP时:
XIo_Out32 (TXbarbase + TX_CONFIG_ADDRESS, testmode);
XIo_Out32 (TXbarbase + RX_CONFIG_ADDRESS, testmode);