2011-05-21 43 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 .:我知道這是一個老問題,你可能會很快找到你的答案:)