2011-05-21 18 views
1

我正在为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我的英文不好

回答

1

什么是你正在试图访问你的董事会的内部块RAM的原因是什么?如果您在您的FPGA上使用Programmed I/O(PIO),我认为设备驱动程序(您的设备是PCI Express接口)的正常行为就足够了。当您写入设备驱动程序时,数据将通过在FPGA端下载IP内核(也反向)传输到Block RAM。

查看来自Xilinx的xapp1022(存储器端点测试)软件包中的Linux驱动程序。

P.S .:我知道这是一个老问题,你可能会很快找到你的答案:)