我正在为Xilinx Virtex-6 X8 PCI Express Gen 2评估/开发套件SX315T FPGA编写器件驱动程序。我的操作系统是openSUSE 11.3 64位。 在此设备的文档中(Virtex-6 FPGA集成块形式PCI Express用户指南UG517(v5.0)2010年4月19日,第219页)说:
PIO设计是一个简单的仅限目标的应用程序,它与Endpoint for PCIe核心的交易(TRN)接口,作为客户构建自己设计的起点。包括以下功能:
•使用内部Xilinx FPGA模块的四个特定于事务的2 KB目标区域 RAM,提供8192字节的总目标空间
•支持单个DWORD有效负载读写PCI Express事务 支持完成TLP的32/64位地址存储空间和I / O空间
•利用核心的trn_rbar_hit_n [6:0]信号来区分TLP目的地 基地址寄存器
•提供针对32位,64位和128位TRN优化的单独实现 接口
在设备中可用BAR0和BAR2长度为128个字节。 我正在尝试访问内部Xilinx FPGA Block RAM,因为我在虚拟空间内核中映射BAR0。
struct pcie_dev {
struct pci_dev* dev;
struct cdev chr_dev;
atomic_t dev_available;
u32 IOBaseAddress;
u32 IOLastAddress;
void* __iomem bar;
void *virt_addr;
u32 length;
unsigned long sirqNum;
void *private_data; };
struct pcie_dev cur_pcie_dev;
cur_pcie_dev.IOBaseAddress = pci_resource_start(dev, 0);
cur_pcie_dev.IOLastAddress = pci_resource_end(dev, 0);
cur_pcie_dev.length=pci_resource_len(dev,0);
cur_pcie_dev.bar=pci_iomap(dev, 0,cur_pcie_dev.length);
IOBaseAddress是0xfbbfe000 IOLastAddress是0xfbbfe07f 长度= 128;
使用IOCTL我尝试写入/读取数据。
case IOCTL_INFO_DEVICE:
{
u32 *rcslave_mem = (u32 *)pCur_dev->bar;
u32 result = 0;
u32 value = 0;
int i;
for (i = 0; i <2048 ; i++) {
printk(KERN_DEBUG "Writing 0x%08x to 0x%p.\n",
(u32)value, (void *)rcslave_mem + i);
iowrite32(value, rcslave_mem + i);
value++;
}
/* read-back loop */
value = 0;
for (i = 0; i < 2048; i++) {
result = ioread32(rcslave_mem + i);
printk(KERN_DEBUG "Wrote 0x%08x to 0x%p, but read back 0x%08x.\n",
(u32)value, (void *)rcslave_mem + i, (u32)result);
value++;
}
但事实证明只能写入和读取32个值。根据我的理解,录制发生在BAR0(4字节* 32值= 128字节),但不在内部Xilinx内存中。我试图走另一条路。
cur_pcie_dev.IOBaseAddress = pci_resource_start(dev, 0);
cur_pcie_dev.IOLastAddress = pci_resource_end(dev, 0);
cur_pcie_dev.length=pci_resource_len(dev,0);
flags = pci_resource_flags(dev,0);
if (flags & IORESOURCE_MEM) {
if (request_mem_region(cur_pcie_dev.IOBaseAddress,cur_pcie_dev.length, DEVICE_NAME)== NULL) {
return -EBUSY;}
cur_pcie_dev.virt_addr=ioremap_nocache(cur_pcie_dev.IOBaseAddress,cur_pcie_dev.length);
if (cur_pcie_dev.virt_addr == NULL) {
printk(KERN_ERR "ERROR: BAR%u remapping FAILED\n",0);
return -ENOMEM;
}
printk(KERN_INFO " Allocated I/O memory range %#lx-%#lx\n", cur_pcie_dev.IOBaseAddress,(cur_pcie_dev.IOBaseAddress+cur_pcie_dev.length-1));
} else {
printk(KERN_ERR "ERROR: Invalid PCI region flags\n");
return -EIO;
}
然后
address = ((unsigned int)pCur_dev->virt_addr+pd.Address);
iowrite32(pd.Value,(unsigned int*) address);
address = ((unsigned int)pCur_dev->virt_addr+pd.Address);
pd.Value = ioread32((unsigned int *)address);
我使用求和虚拟地址和指定用户的地址。但结果是读/写操作也不正确。告诉我我做错了什么。
P.S.Sryry我的英语不好答案 0 :(得分:1)
您尝试访问主板的内部Block RAM的原因是什么?我认为如果在FPGA上使用Programmed I / O(PIO),设备驱动程序(您的设备是PCI Express接口)的正常行为就足够了。当您写入设备驱动程序时,数据将通过FPGA端下载的IP内核(以及相反的方式)传输到Block RAM。
在Xilinx的xapp1022(内存端点测试)包中查看Linux驱动程序。
P.S。:我知道这是一个老问题,你可以尽快找到答案:)