免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: gaoping561
打印 上一主题 下一主题

疑问: PCIe BAR 只有32bit, 怎么在64bit kernel上使用?? [复制链接]

论坛徽章:
0
21 [报告]
发表于 2010-09-05 22:35 |只看该作者
我也是这么猜测的, 但是我又发现一个矛盾的地方。

PCI设备通过pci_alloc_consistent分配DMA空间,返回一 ...
gaoping561 发表于 2010-09-01 17:10



    你对DMA的理解是错误的,还是看看驱动的DMA是怎么写的再说吧。

论坛徽章:
0
22 [报告]
发表于 2010-09-06 10:02 |只看该作者
本帖最后由 gaoping561 于 2010-09-06 10:07 编辑

回复 20# Solaris12
  1. if (x2apic_enabled())
  2.                         msg->address_hi = MSI_ADDR_BASE_HI |
  3.                                           MSI_ADDR_EXT_DEST_ID(dest);
  4.                 else
  5.                         msg->address_hi = MSI_ADDR_BASE_HI;
复制代码
msi_compose_msg里 这个case 会不会成立?如果成立的话还会需要64bit address. 貌似2xapic_enabled 多处理器系统下才可能成立,这样说来一般的单CPU系统不要考虑这个问题

论坛徽章:
0
23 [报告]
发表于 2010-09-06 10:18 |只看该作者
回复 21# Solaris12


    还请详细斧正,pci_alloc_consistent 分配一个缓冲区,建立内核虚拟地址和PCI总线地址的映射,也就是说pci设备操作dma_addr_t这个地址,等同于操作与之对应的内核虚拟地址。
具体过程就是,把dma_addr_t 赋给pci设备的DMA读/写地址寄存器,PCI设备DMA的时候读/写dma_addr_t 这个地址,然后对应的内核虚拟地址里也有了相应的数据,是不是这个过程?

论坛徽章:
0
24 [报告]
发表于 2010-09-06 12:26 |只看该作者
msi_compose_msg里 这个case 会不会成立?如果成立的话还会需要64bit address. 貌似2xapic_enabled 多处理器系统下才可能成立,这样说来一般的单CPU系统不要考虑这个问题



x2apci和以前的apic都是多处理器的,至少以前的apic使用4G以下的地址,x2paic的规范我没看过。

论坛徽章:
0
25 [报告]
发表于 2010-09-06 12:28 |只看该作者
本帖最后由 Solaris12 于 2010-09-06 15:37 编辑
还请详细斧正,pci_alloc_consistent 分配一个缓冲区,建立内核虚拟地址和PCI总线地址的映射,也就是说pci设备操作dma_addr_t这个地址,等同于操作与之对应的内核虚拟地址。
具体过程就是,把dma_addr_t 赋给pci设备的DMA读/写地址寄存器,PCI设备DMA的时候读/写dma_addr_t 这个地址,然后对应的内核虚拟地址里也有了相应的数据,是不是这个过程?]



  》  dma_addr_t这个地址应该是host memory的地址,虽然没看过Linux但我猜也能猜出来。

  》 ”建立内核虚拟地址和PCI总线地址的映射“这句话纯属你自己的臆测。

有了后来提供的手册,基本上我能知道pci_alloc_consistent干什么的了。

pci_alloc_consistent 在有IOMMU的时候是要建立IOMMU的页表的映射的,没有IOMMU的时候,就是直接把host memory的物理地址直接返回。

即使IOMMU建立了映射,这个映射也是DMA的总线地址到host memory的物理地址的映射。

这个地址和bar映射设备内存空间里寄存器的地址没有关系。之前看你是问和bar相关的东西,不知道怎么扯到DMA上来的。

32位寻址能力的DMA在没有IOMMU的时候使用bounce buffer的设计,在有IOMMU的时候,如果IOMMU可以确保该DMA使用低于4G的总线空间地址,那就不需要bounce buffer了。

论坛徽章:
0
26 [报告]
发表于 2010-09-06 14:43 |只看该作者
本帖最后由 gaoping561 于 2010-09-06 14:47 编辑
dma_addr_t这个地址应该是host memory的地址,虽然没看过Linux但我猜也能猜出来。

   ”建立内 ...
Solaris12 发表于 2010-09-06 12:28



    伙计,谢谢你的回复,但是很遗憾我觉得你猜错了

引用<<Essential.Linux.Device.Drivers>>
void *pci_alloc_consistent(struct pci_dev *pdev,
                           size_t size,
                           dma_addr_t *dma_handle);
This function allocates a DMA buffer, generates its bus address, and returns the associated kernel virtual address. The first two arguments respectively hold the PCI device structure (which is discussed later) and the size of the requested DMA buffer. The third argument, dma_handle, is a pointer to the bus address that the function call generates

在《PCI Express体系机构导读》P329,进行DMA操作的地址是PCI设备使用的,而且这个地址只能是PCI总线的物理地址,尽管在x86中,存储器域物理地址到PCI总线域物理地址的转换非常简单,是直接相等的关系,仅仅是数值相同而已,但是两者的意义是完全不同的。

dma_addr_t显然不是host memory地址而是PCI总线地址

论坛徽章:
0
27 [报告]
发表于 2010-09-06 14:52 |只看该作者
本帖最后由 Solaris12 于 2010-09-06 14:58 编辑
伙计,谢谢你的回复,但是很遗憾我觉得你猜错了

引用<<Essential.Linux.Device.Drivers>>
void *pci_alloc_consistent(struct pci_dev *pdev,
                           size_t size,
                           dma_addr_t *dma_handle);
This function allocates a DMA buffer, generates its bus address, and returns the associated kernel virtual address. The first two arguments respectively hold the PCI device structure (which is discussed later) and the size of the requested DMA buffer. The third argument, dma_handle, is a pointer to the bus address that the function call generates

在《PCI Express体系机构导读》P329种,进行DMA操作的地址是PCI设备使用的,而且这个地址只能是PCI总线的物理地址,尽管在x86中,存储器域物理地址到PCI总线域物理地址的转换非常简单,是直接相等的关系,仅仅是数值相同,但是两者的意义是完全不同的

显然不是host memory地址而是PCI总线地址


我之前没有猜错,只不过没有考虑有IOMMU的情况。

在有IOMMU的时候,是总线地址。在没有IOMMU的时候是Host memory的虚拟地址。

在有IOMMU的时候,总线地址的空间其实是从IOMMU的页表里拿的,而这个地址是否是4G以上取决于IOMMU的能力,而且这个总线地址对应的地址还是host memory物理地址,这是完全和PCI内存空间BAR寄存器没有什么关系的。

而且,这个接口看起来和Solaris的接口思想差不多。

论坛徽章:
0
28 [报告]
发表于 2010-09-06 15:13 |只看该作者
回复 26# gaoping561


    总线设备使用总线地址没错.bar,和msi本质都只能使用总线地址.因为使用这个地址必须在总线上发生一个寻址.
但是也必要太较真.
就好象使用定义和实现的区别一样.效果达到就可以了.
大家从不同的角度看问题而已...

论坛徽章:
0
29 [报告]
发表于 2010-09-06 15:24 |只看该作者
回复  gaoping561


    总线设备使用总线地址没错.bar,和msi本质都只能使用总线地址.因为使用这个地址 ...
epegasus 发表于 2010-09-06 15:13



这里面要区分清楚的是 IOMMU的总线地址和MMU的虚拟地址还有MMU物理地址的关系。

论坛徽章:
0
30 [报告]
发表于 2010-09-06 15:47 |只看该作者
我的内存有24G啊,DMA很可能访问4G以上了。

如果是对等映射,这样看来如果DMA操作4G以上物理内存,那dma_addr_t肯定是64位总线地址了,至少PCIE设备设计的时候,DMA寄存器要64bit。

google了一把,关于PCI的讨论集中在32bit DMA如何访问高4G内存的问题,一般都是回弹缓冲或者IOMMU

可是我关心的32bit BAR address register 怎么搞,是不需要关心还是也需要搞IOMMU才行?或者必须得把设备设计成64bit addressing

背景就是,现在有一个PCIE的设备,FPGA实现的,目前所有地址register只支持32bit addressing,怎么用在x86_64上。


32位的BAR在x86上就是映射到4GB以下的host memory的物理地址空间的。

这个和DMA未必有关联,DMA的限制要看DMA部件的寻址寄存器的实现。

很多设备都是32位bar但确是64位DMA的能力, 例如Intel的很多网卡,它的DMA总线地址是通过ring - buffer这样的方式交给DMA部件的,并不是要把地址写到内存空间的寄存器上。

即使写道内存空间的寄存器上,我们也可以用两个32位寄存器存放一个大于4GB的DMA总线地址。

总之,DMA的能力要看DMA的寻址寄存器。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP