linux 内存驱动程序,Linux设备驱动程序DMA内存缓冲区未按PCIe硬件顺序排列

阅读: 评论:0

linux 内存驱动程序,Linux设备驱动程序DMA内存缓冲区未按PCIe硬件顺序排列

linux 内存驱动程序,Linux设备驱动程序DMA内存缓冲区未按PCIe硬件顺序排列

我正在开发Xilinx Virtex 6 PCIe定制板卡的设备驱动程序。 在做DMA写(从主机到设备)会出现以下情况:Linux设备驱动程序DMA内存缓冲区未按PCIe硬件顺序排列

用户空间应用:

a. fill buffer with the following byte pattern (tested up to 16kB)

00 00 .. 00 (64bytes)

01 01 .. 00 (64bytes)

...

ff ff .. ff (64bytes)

00 00 .. 00 (64bytes)

01 01 .. 00 (64bytes)

etc

b. call custom ioctl to pass pointer to buffer and size

内核空间:

a. retrieve buffer (bufp) with

copy_from_user(ptdev->kbuf, bufp, cnt)

b. setup and start DMA

b1. //setup physical address

iowrite32(cpu_to_be32((u32) ptdev->kbuf_dma_addr),

ptdev->region0 + TDO_DMA_HOST_ADDR);

b2. //setup transfer size

iowrite32(cpu_to_be32(((cnt+3)/4)*4),

ptdev->region0 + TDO_DMA_BYTELEN);

b3. //memory barrier to make sure kbuf is in memorry

mb();

//start dma

b4. iowrite32(cpu_to_be32(TDO_DMA_H2A | TDO_DMA_BURST_FIXED | TDO_DMA_START),

ptdev->region0 + TDO_DMA_CTL_STAT);

c. put process to sleep

wait_res = wait_event_interruptible_timeout(ptdev->dma_queue,

!(tdo_dma_busy(ptdev, &dma_stat)),

timeout);

d. check wait_res result and dma status register and return

Note that the kernel buffer is allocated once at device probe with:

ptdev->kbuf = pci_alloc_consistent(dev, ptdev->kbuf_size, --512kB

&ptdev->kbuf_dma_addr);

设备PCIE TLP转储(通过逻辑分析仪获得在Xilinx核心之后):

a. TLP received (by the device)

a1. 40000001 0000000F F7C04808 37900000 (MWr corresponds to b1 above)

a1. 40000001 0000000F F7C0480C 00000FF8 (MWr corresponds to b2 above)

a1. 40000001 0000000F F7C04800 00010011 (MWr corresponds to b4 above)

b. TLP sent (by the device)

b1. 00000080 010000FF 37900000 (MRd 80h DW @ addr 37900000h)

b2. 00000080 010000FF 37900200 (MRd 80h DW @ addr 37900200h)

b3. 00000080 010000FF 37900400 (MRd 80h DW @ addr 37900400h)

b4. 00000080 010000FF 37900600 (MRd 80h DW @ addr 37900600h)

...

c. TLP received (by the device)

c1. 4A000020 00000080 01000000 00 00 .. 00 01 01 .. 01 CplD 128B

c2. 4A000020 00000080 01000000 02 02 .. 02 03 03 .. 03 CplD 128B

c3. 4A000020 00000080 01000000 04 04 .. 04 05 05 .. 05 CplD 128B

c4. 4A000020 00000080 01000000 06 06 .. 0A 0A 0A .. 0A CplD 128B <=

c5. 4A000010 00000040 01000040 07 07 .. 07 CplD 64B <=

c6. 4A000010 00000040 01000040 0B 0B .. 0B CplD 64B <=

c7. 4A000020 00000080 01000000 08 08 .. 08 09 09 .. 09 CplD 128B <=

c8. 4A000020 00000080 01000000 0C 0C .. 0C 0D 0D .. 0D CplD 128B

.. the remaining bytes are transfered correctly and

the total number of bytes (FF8h) matches the requested size

signal interrupt

现在这个表面存储器命令er ror发生的概率很高(0.8 < p < 1),并且排序不匹配发生在传输中不同的随机点。

编辑:请注意,上述点c4将表明内存驱动程序没有按正确顺序填充内存(我假设内存控制器使用连续内存填充TLP)。 64B是缓存行的大小,这可能与缓存操作有关。

当我禁用与内核缓冲区高速缓存,

echo "base=0xaf180000 size=0x00008000 type=uncachable" > /proc/mtrr

错误仍然发生,但更多的很少(P < 0.1和依赖于传输大小)

这只是发生在一个i7-基于4770(Haswell)的机器(在3台相同的机器上进行测试,配有3块板)。 我尝试了内核2.6.32(RH6.5),库存3.10.28和库存3.13.1,结果相同。

我在基于i7-610 QM57的机器和Xeon 5400机器上尝试了代码和设备,没有出现任何问题。

欢迎任何想法/建议。

此致

克劳迪奥

2014-02-07

Claudio

本文发布于:2024-02-02 16:19:19,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170686195944967.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23