PCI内核模块无法读取BAR

时间:2018-04-10 13:07:28

标签: embedded-linux pci

我在PowerPC处理器上为自定义板写了我的pci驱动程序(p2020)。我使用X520 ehternet适配器进行测试。当我为x86编译它时,它工作正常,但是当我为自定义板编译它时,它在所有BAR上只读取0xffffffff。 这是我的代码:

printk(KERN_INFO "sol probe\r\n");

bar_mask = pci_select_bars(dev, IORESOURCE_MEM_64);
printk("bar_mask 0x%08x PCI_NUM_RESOURCES %d\r\n", bar_mask, PCI_NUM_RESOURCES);

mmio_base = pci_resource_start( dev, bar_num );
mmio_size = pci_resource_len( dev, bar_num );
printk("sol dev BAR%i address = %lx, len = %lx\n", bar_num, mmio_base, mmio_size);

/*
if(pci_enable_msi(dev)){
    printk(KERN_ALERT "Cannot enable MSI\r\n");
}
*/

if(pci_user_write_config_word(dev, 0x04, 0x0000)){
    printk(KERN_ALERT "Cannot write command config\r\n");
}

if(pci_user_write_config_byte(dev, 0x0c, 0x0000)){
    printk(KERN_ALERT "Cannot write cache line size config  config\r\n");
}

read_config32(dev, 0, 0x3c);

if(pci_request_region(dev, bar_num, SOL_DRV_NAME)){
    printk(KERN_ALERT "I/O resource busy\r\n");
        return -EBUSY;
}

if(pci_enable_device(dev)){
    printk(KERN_ALERT "Cannot enable memory space access!\r\n");
    return ENODEV;
}

iomap = pci_iomap(dev, bar_num, 0);
if ( !iomap  )
{   
    printk(KERN_ALERT "Cannot IO map at PCI BAR%i!\n", bar_num);
        return -ENOSPC;
}

ret = pci_resource_flags(dev, bar_num);
printk(KERN_ALERT "flags 0x%x08\n", ret);
if(!(ret & IORESOURCE_MEM)){
    printk(KERN_ALERT "IORESORCE_MEM flag isn't seti\n");
}
read_bars(0xf);
return 0;

阅读BAR

static void read_bars(unsigned int n){
unsigned long i;
printk(KERN_INFO "iomap\t0x%08x\r\n", (u32)iomap);
for(i = 0; i < (n  << 2); i+=4){
    printk(KERN_INFO "bar 0x%08lx\t: 0x%08x\r\n",\
        i, readl(iomap+i));
}

2 个答案:

答案 0 :(得分:0)

dts中pcie0的寄存器范围不正确。在纠正之后,它会起作用。

答案 1 :(得分:0)

您可以阅读有关设备树使用情况(dts)here

的信息

我有错误的参数&#34;范围&#34;。它描述了将PCI BAR内存空间映射到CPU内存空间的附加内容。我的补丁是

<       ranges = <0x2000000 0x0 0xc0000000 0 0xc0000000 0x0 0x20000000
<             0x1000000 0x0 0x00000000 0 0xffc20000 0x0 0x10000>;
>       ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000
>             0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;