PCI驱动分为两种类别:
1.CPU通过io方式访问的PCI设备驱动
2.dma方式的PCI设备驱动
其实就是两种方式
在io方式下访问PCI/SRIO设备
通过outbound寄存器将本地存储器映射到remote端pci设备 --------------------------------IOMMU过程
同时一般需要将CPU物理地址转换成本地存储器地址----------------------MMU过程
MMU和IOMMU实现一般是在PCI controller下实现的
比如mot85xxpci.c中mot85xxBridgeInit函数中就是设置了PCI port和outbound寄存器
Linux平台PCI设备的总线地址(物理地址)为0x80000000,CPU物理地址(虚拟地址)为0xc0000000,对应的内存存储器是0
它的映射过程如下:
0xc0000000------> 0 ------------------------>0x80000000
注意:我们写PCI驱动时必须要MMU映射,比如在linux下需要ioremap,而在vxworks下一般不需要,因为sysLib.c中的sysPhysMemDesc数组已经定义了。当然我们也可以通过调用pciConfigInLong,pciConfigInByte获得设备映射的内存基地址memBase和I/O基地址ioBase以及中断号irq,然后sysMmuMapAdd((void*)memBase,MEM_SIZE)来动态的映射内存空间。(第二种比较灵活)
dma方式PCI/SRIO设备驱动
在这个方式下,本地存储器通过inbound寄存器建立与remote端PCI设备的映射关系(不经过CPU)
此时我们不需要添加MMU映射,因为是inbound方式访问,CPU不会访问PCI设备。
但是dma控制器可能使用板卡的,也可能使用remote端的PCI设备,比如张松岭的SRIO转万兆网关。
SRIO转万兆的情况是我们也需要一个mot85xxsrio.c文件即SRIO controller驱动,这里我们设置srio port和inbound寄存器(因为是dma方式,所以用inbound)
同时我们需要SRIO 设备驱动
在SRIO设备驱动中我们要实现SRIO设备的逻辑功能,不用MMU映射,因为没有CPU访问SRIO设备。
其实归纳起来我们完全可以讲PCI controller驱动和PCI设备驱动合并起来,但是那样的话,就是不方便移植新的驱动。
比如PCI插槽,由PCI网卡完成PCI声卡,我们在驱动中还要重新对PCI插槽设置PCI port和inbound/outbound寄存器。
而我们将PCI网卡和PCI声卡的共性提取出来(PCI port和inbound/outbound寄存器的设置),即将PCI插槽的引脚属性和访问方式放到PCI controller驱动中。
这样我们每次就只需要实现具体的PCI网卡驱动的逻辑功能。
在我的资源里有一个
vxworks PCI设备初始化编程的过程,可以学习一下
http://download.csdn.net/detail/qingfengtsing/7198309
另外有一个链接:一种PCI设备高效率DMA传输方法
http://www.docin.com/p-200241159.html