是否有可能对PCI BAR内存进行MMAP?

时间:2016-09-18 22:04:30

标签: driver pci

我想用户从PCIe板访问内存,该板提供1GB内存和BAR0。 目前我只使用我的字符设备驱动程序的读写功能,这在8x PCIe Gen3上非常慢(1MB / s读取和16MB / s写入)。

static ssize_t
MPD_read(
    struct file *filp,
    char *buffer,
    size_t bufferSize,
    loff_t *offset )
{
    unsigned long unusedBytes = copy_to_user(
        ( void * ) buffer,
        MPD_AdapterBoard.bars[ 0 ].barHWAddress,
        bufferSize );
    return 0;
}

static ssize_t
MPD_write(
    struct file *filp,
    const char *buffer,
    size_t bufferSize,
    loff_t *offset )
{
    unsigned long unusedBytes = copy_from_user(
        MPD_AdapterBoard.bars[ 0 ].barHWAddress,
        ( void * ) buffer,
        bufferSize );
    return 0;
}

是否可以使用MMAP(使用.mmap文件操作)来获得更快的速度? 或者DMA是唯一的选择吗?

提前致谢!

/ Jesko

1 个答案:

答案 0 :(得分:0)

我发现它是如何工作的:

static int
    MPD_mmap(
    struct file *filp,
    struct vm_area_struct *vma )
{
    unsigned long offset;

    offset = vma->vm_pgoff << PAGE_SHIFT;
    if (( offset + ( vma->vm_end - vma->vm_start )) > MPD_AdapterBoard.bars[ 0 ].barSizeInBytes )
    {
        return -EINVAL;
    }

    offset += ( unsigned long ) MPD_AdapterBoard.bars[ 0 ].mmioStart;

    vma->vm_page_prot = pgprot_noncached( vma->vm_page_prot );

    if ( io_remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot ))
    {
        return -EAGAIN;
    }
    return 0;
}

注意:这是正在进行的工作,因此错误检查相当有限。

为了帮助这里的人,可以从这里下载完整的代码,包括测试程序:https://github.com/jesko42/minipci