我正在为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页)中说:访问内部Xilinx FPGA Block RAM
PIO设计是一个简单的仅限目标的应用程序,与Endpoint的PCIe内核交易(TRN)接口连接,并作为客户构建自己设计的起点。在包括如下功能:
•四个使用内部的Xilinx FPGA的特定交易2 KB的目标区域框 RAM中,提供8192个字节的总目标空间
•支持单一DWORD有效载荷的读取和写入的PCI Express交易 32-/64位地址的存储器空间和I /与完成的TLP支持
•利用核心的trn_rbar_hit_n O空间[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);
CH365的是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.Sorry我的英文不好