PCI9054读取BAR2数据所遇到的奇怪问题!

时间:2022-09-16 22:05:37
最近在做FPGA+PCI9054的数据采集卡项目,用的是飞思卡尔imx6q嵌入式平台,PCI驱动用的PlxSdk V7.20版本,在读取BAR2中数据时遇到了一个非常非常奇怪的问题,小弟才疏学浅,百思不得其解,特来求助!

下面的代码几乎就是PlxSdk提供的参考代码,我没有做任何改动:

// Test Code.
U8 i;
U32 value;
U32 VA[6]; // Virtual address

for(i=0;i<6;i++){
rc = PlxPci_PciBarMap(Device,i,&(VA[i]));
if(rc != PLX_STATUS_OK){
printf("API Failed. rc = %d\n",rc);
}
}
printf(
" BAR0 VADDR = 0x%08x.\n"
" BAR1 VADDR = 0x%08x.\n"
" BAR2 VADDR = 0x%08x.\n"
" BAR3 VADDR = 0x%08x.\n"
" BAR4 VADDR = 0x%08x.\n"
" BAR5 VADDR = 0x%08x.\n"
,VA[0],VA[1],VA[2],VA[3],VA[4],VA[5]);


// Read a 32-bit value from Space 0 (For 9054, Space 0 is at PCI BAR 2)
value = *(U32*)(VA[2]+0x174);
*(U32*)(VA[2]+0x174) = value;

//printf("00000000000000000000 %d\n",value);

// Set bit 7 in local register 1Ch (PLX registers are at BAR 0)
value = *(U32*)(VA[0] + 0x1c);

printf("11111111111111111111111\n");
// Set bit 7
value = value | (1 << 7);

printf("222222222222222222222\n");
// Write register
*(U32*)(VA[0] + 0x1c) = value;

printf("33333333333333333333\n");

return 0;


当我注释掉中间那行printf的时候,程序可以正常执行退出,打印如下:
Plx9054: Mapped Phys (01300000) ==> User VA (76fc6000)
API Failed. rc = 522
Plx9054: Mapped Phys (01100000) ==> User VA (76cf2000)
Plx9054: Mapped Phys (01200000) ==> User VA (76bf2000)
API Failed. rc = 522
API Failed. rc = 522
        BAR0 VADDR = 0x76fc6000.
        BAR1 VADDR = 0x00000000.
        BAR2 VADDR = 0x76cf2000.
        BAR3 VADDR = 0x76bf2000.
        BAR4 VADDR = 0x00000000.
        BAR5 VADDR = 0x00000000.
11111111111111111111111
222222222222222222222
33333333333333333333
root@imx6qsabresd:/mnt/App#

但如果我打开中间printf的注释,就会报一个系统级的错误,打印如下:
Plx9054: Mapped Phys (01300000) ==> User VA (76f7f000)
API Failed. rc = 522
Plx9054: Mapped Phys (01100000) ==> User VA (76cab000)
Plx9054: Mapped Phys (01200000) ==> User VA (76bab000)
API Failed. rc = 522
Unhandled fault: external abort on non-linefetch (0x1018) at 0x76cab174
API Failed. rc = 522
        BAR0 VADDR = 0x76f7f000.
        BAR1 VADDR = 0x00000000.
        BAR2 VADDR = 0x76cab000.
        BAR3 VADDR = 0x76bab000.
        BAR4 VADDR = 0x00000000.
        BAR5 VADDR = 0x00000000.
Bus error
root@imx6qsabresd:/mnt/App# 

我只不过是希望输出value的值观察一下而已......

2 个解决方案

#1


程序中PlxPci_PciBarMap的作用就是将Local地址空间直接映射到用户虚拟空间,这样用户就可以直接操作了。

#2


自己解决了,原因是没有配置PCI9054位于BAR0偏移0x04的LAS0BA寄存器的最后一位,该位管理着BAR2是否可用,在访问BAR2的地址空间之前,需要先使能BAR2。

value = *(U32*)(VA[0]+0x04);
value |= 0x00000001;
*(U32*)(VA[0]+0x04) = value;


另外,类似的Unhandled fault: external abort on non-linefetch (0x1018) at 0x76cab174问题,大多数都是由于访问了未使能的资源引起的。

#1


程序中PlxPci_PciBarMap的作用就是将Local地址空间直接映射到用户虚拟空间,这样用户就可以直接操作了。

#2


自己解决了,原因是没有配置PCI9054位于BAR0偏移0x04的LAS0BA寄存器的最后一位,该位管理着BAR2是否可用,在访问BAR2的地址空间之前,需要先使能BAR2。

value = *(U32*)(VA[0]+0x04);
value |= 0x00000001;
*(U32*)(VA[0]+0x04) = value;


另外,类似的Unhandled fault: external abort on non-linefetch (0x1018) at 0x76cab174问题,大多数都是由于访问了未使能的资源引起的。