我正在编写一个设备驱动程序来访问PCIe卡上FPGA中的内存.
卡片启动并被探测/发现: -
的/ proc/IOMEM
80000000-840fffff : PCI Bus #03
80000000-83ffffff : 0000:03:00.0
84000000-840fffff : 0000:03:00.0
Run Code Online (Sandbox Code Playgroud)
所以,读LDD /等我编写了一个调用request_mem_region的80000000,并通过请求指向它的指针ioremap_nocache
1)我是否需要request_mem_region和a一样ioremap_nocache,我不能只使用后者?
/ proc/iomem insmod我的设备驱动程序后: -
80000000-840fffff : PCI Bus #03
80000000-83ffffff : 0000:03:00.0
80000000-8003ffff : fp2
84000000-840fffff : 0000:03:00.0
Run Code Online (Sandbox Code Playgroud)
2)对我来说看起来不太合适......?
无论如何,读取不起作用(它没有编码如下,它有检查等): -
#define BAR_ADDR 0x80000000
void *base = ioremap_nocache(BAR_ADDR, 0x40000);
void *address = base + KNOWN_REG_LOCATION;
int data = ioread32(address);
printk("fp2: address:0x%08x, data:0x%08x\n", address, data);
Run Code Online (Sandbox Code Playgroud)
产出: -
address:0xfd500000, data:0xffffffff
Run Code Online (Sandbox Code Playgroud)
我可以x80000000+KNOWN_REG_LOCATION从mmap用户空间中读取.
3)我已经尝试过__raw_readl/ readl没有运气.
4)我可以只读取当前映射的地址x80000000吗?
伊恩
我为设备编写了一个PCI驱动程序(完整源代码).寄存器空间的映射应该是相同的.我就是这样做的.
dm7820_device->pci[region].virt_addr = ioremap_nocache(address, length);
if (dm7820_device->pci[region].virt_addr == NULL) {
printk(KERN_ERR "%s: ERROR: BAR%u remapping FAILED\n",
&((dm7820_device->device_name)[0]), region);
dm7820_release_resources();
return -ENOMEM;
}
if (request_mem_region(address, length, &((dm7820_device->device_name)[0])) == NULL) {
printk(KERN_ERR "%s: ERROR: I/O memory range %#lx-%#lx allocation FAILED\n",
&((dm7820_device->device_name)[0]), address, (address + length - 1));
dm7820_release_resources();
return -EBUSY;
}
Run Code Online (Sandbox Code Playgroud)
地址和长度值从pci_resource_start()和pci_resource_length()调用返回.
然后你可以使用ioread32()使用它来访问它dm7820_device->pci[region].virt_addr + <register offset>
如果您有任何疑问,请告诉我.