linux pcie rescan_pcie驱动开发

linux pcie rescan_pcie驱动开发PCIe的数据传输前文说了数据传输的两大要素,分别是地址信息和Producer-Consumer模型机制。这里以PCIe为例再做一个具体的描述,从硬件系统角度来看PCIe设备是如何工作的。此处仅考虑存在大流量的PCIe设备,不考虑如PC

PCIe的数据传输   前文说了数据传输的两大要素,分别是地址信息和Producer-Consumer模型机制。这里以PCIe为例再做一个具体的描述,从硬件系统角度来看PCIe设备是如何工作的。此处仅考虑存在大流量的PCIe设备,不考虑如PCIe串口卡、GPIO卡一类的设备。   设备或模块需要启动时,需要访问出口和入口,其中入口作为配置接口和状态读取;访问请求出口,又包括数据读取和写出两个方向,一般来说,设备内包含DMA引擎,访问请求出口基本涵盖了设备除配置外的所有流量。根据简单的系统结构模型来看,PCIe设备既属于广义DMA,也属于存储体。    从地址域理解PCIe   系统内的所有访问操作均是基于地址进行处理的,PCIe作为系统内的重要角色,同样是基于地址进行操作的。下图为PCIe协议对于PCIe连接拓扑的简要描述,其中Root Complex(RC)为I/O层次结构的根节点,将PCIe设备与CPU/Memory连接到一起,与其余PCIe设备(包括Switch)连接的端口称为RootPort;Endpoint就是PCIe设备,系统配置设备启动,后续该设备再启动DMA执行相关任务;Switch可以将一个PCIe端口扩展为多个端口,还可以进行级连扩展,连接更多的PCIe设备。
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发   先看PCIe设备的访问入口方向,存在两个问题,一是设备如何声称所需的配置空间,二是访问操作如何转发至对应设备。协议定义了两种类型的配置空间,分别是Type0和Type1,其中Type0用于描述PCIe设备相关属性,Type1用于描述RootPort和Switch接口相关属性。   Type0配置空间解决了第一问题,下图为Type0 Configuration Space Header,通过Base Address Registers声称该设备需要的配置空间大小。
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发   每个PCIe设备最大可声明为6个Bar,可配置大小、属性、32bit/64bit地址区间,下图分别描述了定义为Memory和I/O属性的Bar空间配置。如果需要配置为64bit地址,需要占用两个Bar,因此最多只能定义3个64bit地址的Bar空间。   那设备又是如何声明Bar空间大小的呢?直接将低位偏移地址域段固定接为0,如需要1MB的空间大小,对应为2的20次方,将Bar的低20bit除属性配置外均固定为0。配置空间先对该寄存器写入全1,再读取,通过返回值判断该Bar空间的大小。
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发   Type1配置空间解决第二个问题,将访问请求转发至对应设备,下图为Type1 Configuration Space Header,用于描述RootPort/Switch相关属性。使用Base/Limit定义该Port下面挂接的设备地址区间,命中该空间的访问请求,则转发至该端口,进而再发送至对应的设备;该配置空间内又分别定义了I/O、32bit地址和64bit地址的区间范围,其中I/O空间最小可定义为4Kbyte,32bit/64bit地址区间最小可定义为1Mbyte。访问请求命中的条件为,大于等于Base定义地址,小于等于Limit定义的地址。
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发   再看PCIe设备的访问出口方向,通过配置启动后,该设备就可以发出读写请求,通过地址访问系统其余的存储体。   以上从地址域视角介绍了PCIe相关内容,到具体实现还有不少问题,如下为其中的三个。   1) Host(RC)与Device侧的地址关系   一般来说,Host与Device各自维护着一个系统,各有其地址管理系统。按照之前提到的概念,统一语言是对话的前提,在这里地址就是语言,两者之间的语言是不统一的。因此,两者之间必须有中介模块,用于做语言的转换,也就是地址域的转换。   下图为PCIe设备连接到Host侧的示意图,包括Host和Device的相关模块。两侧PCIe相关模块均存在访问请求的出口和入口,也即Master/Slave端口,其访问请求均是基于各自的地址域进行处理的。   Device,即Endpoint,使用的是Type0配置空间,其接收到的请求使用的是Host侧的地址域,因此需要进行地址域转换;对于相反方向,也即Device to Host方向,同样需要做地址转换,将Device侧的地址域转换为Host侧的地址。为什么都在Device侧进行转换?这是由于PCIe拓扑内,均是使用RC侧地址进行路由转发的。图中的RX/TX Address Translate就是地址转换模块,在RX方向,将命中BAR空间的请求地址转换为Device侧地址,也就是图中的PCIe Master BAR Map;在TX方向,将Device侧的地址转换为Host侧的地址。   图中还有一个重要的模块,就是DMA Engine,可以不需要做地址域的转换,直接进行处理。这是由于该模块刚好处于地址域的边界(虚线),直接使用请求访问方向使用其对应的地址域,因此不再需要做地址转换。   此处描述的是一般情况,根据不同场景,会有一些实现上的区别。   
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发   2) 再谈BAR空间   前面在谈到PCIe Device的BAR空间时,仅仅是作为配置接口,绝大部分的请求访问均是主动发起的,而不是通过BAR空间被动接收的。实际上,BAR空间作为存储体的角色,可以支持较大的地址区间,接收其余模块发过来的大流量读写请求。   另外,使用Type1配置空间的Base/Limit进行地址路由转发,若接收到Device发送的读写请求,又命中了另外一个Port的Base/Limit定义的地址区间,可以直接进行路由转发。这个就是Peer-to-Peer的概念,可以高效使用PCIe链路提供的带宽,又不需要Host侧CPU/Memory进行介入,降低路径延时。   3) 虚拟地址   以上谈到的都是物理地址,实际上很多设备都支持SR-IOV,Device侧发出的地址是虚拟地址。这里涉及到虚拟化相关的内容,将另起一文进行描述。近期梳理了虚拟化的概念之后,相关内容变得清晰,收获很大,而这个基本就是瞬间的事情。之前在老东家,天天接触那些概念,一直都懵懵懂懂的,也就是没有搞清楚这几个概念。    Producer-Consumer模型机制   该模型有两个关键点,一是Flag定义,另外一个是Flag和DATA的观测顺序。PCIe数据传输涉及到了多个Producer-Consumer模型,分类为Host2Device和Device2Host两个方向。   先来看Flag的定义。最简单的方式是直接指定一个地址作为Flag,另外一侧轮询该地址数据或是硬件检测写操作,发现有更新后再去消费数据。另外一种方式则是使用中断。   Device2Host方向,有3种中断上报的机制,分别是INTx/MSI/MSI-X,其中INTx为Message操作,MSI/MSI-X为Memory写操作。网上可以找到很多相关内容,不再重复描述。   Host2Device方向,硬件检测写操作,再生成中断上报到本端系统,后续再执行相关的操作。这一类中断的生成可以有多种实现方式。如NVMe定义的Doorbell寄存器,将指针信息写入该寄存器后,生成中断。或者是在地址转换模块,访问请求命中转换窗口之后,上报中断。这里需要考虑的是如何设计软硬件接口,完成要求功能时,又减少软硬件之间的交互。个人认为NVMe的Doorbell寄存器是更合理的一种方式。   另一个问题是Flag和DATA的观测顺序,这需要生成者和消费者之间,端到端进行保证,但点到点之间可通过不同的机制进行保证。一般来说,都是由数据生产者保证其写入的顺序关系,借由到消费者之间的路径特性,进而确保Flag和DATA的关系。   先看PCIe协议,定义了Transaction Ordering Rules,其中定义为No的域段就是用于保证Flag与DATA之间的顺序关系。除此之外,在访问请求发送至PCIe或者从PCIe Master接口发送至其余模块,则需要基于具体使用的总线协议做具体分析,如使用AXI相同ID保序的规则、Cache一致性协议等等。
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发    以NVMe为例   这里以NVMe作为更具体的例子,描述以PCIe为接口的数据传输。   1)BAR空间分配   协议仅仅要求一个Memory Bar,用于Controller Registers,其余Bar均作为Optional,可进行自定义。该Memory Bar使用BAR0,可定义为32bit或64bit的BAR,Non-prefetchable,建议使用64bit BAR。该BAR空间大小最小可配置为16KBytes,若需要支持更多的Doorbell寄存器或自定义功能,可配置较大的空间。   Controller Registers定义如下图所示,可分为三部分,包括控制寄存器、Doorbell寄存器和Vendor Specific寄存器(Optional)。   可以注意到其控制寄存器非常少,且其中大部分都是Optional。NVMe作为挂接在Host的模块,均是使用前文提到的模块启动方式的第二种,也就是通过配置使能进行启动。仅仅看下图的寄存器,能否看出设备是如何启动的?
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发   Admin Queue Attributes、Admin Submission Queue Base Address和Admin Completion Queue Base Address三个寄存器,再加上Doorbell寄存器,就是作为Host与NVMe设备交互的接口。使用该接口做IO队列的管理,启动数据读写等等流程。   此外,定义了较多的Doorbell寄存器,用于Host向Device更新指针信号。在这里可以先思考一下,仅仅使用这部分的寄存器,host与device是如何进行交互的?   BAR2/3/4/5可以被设置为PMR(Persistent Memory Region)持久性内存区域,可被主机和其他设备访问。如从网卡接收到的报文,可以直接通过Peer-to-Peer(P2P)的方式写入到NVMe设备,无需经过Host CPU和Memory,降低延时。   2)中断定义   主要是device2host的中断,协议可以支持INTx/MSI/MSI-X三种类型的中断,其实现与PCIe协议一致。对于host2device方向,根据具体实现选择方案,如device侧存在系统,则可以检测Doorbell寄存器的写操作,产生中断。   3)数据交互   NVMe设备是基于Producer-Consumer进行数据传输的,其任务处理流程如下所示。   1. Host将一个或多个任务/Command写入到Submission Queue(SQ)队列内;   2. Host写Doorbell寄存器,更新SQ的Tail指针,表示有新任务需要被处理;   3. Device检测到Doorbell寄存器被写入后,与写入前的指针值做比较,将Host新添加的任务搬运到Device侧,也就是消费数据;   4. Device执行新添加的任务;   5. Device完成任务后,将完成状态写入到Host侧Completion Queue(CQ)队列;   6. Device完成状态写入后,再上报中断;   7. Host接收到中断,开始读取CQ内容,判断任务完成状态;   8. Host写Doorbell寄存器,更新CQ的Head指针,表示CQ Entry内容已经被读取。   注意以上流程涉及到多个Producer-Consumer模型,可尝试对其进行分析判断。
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发   NVMe的SQ/CQ队列均采用环形Buffer进行管理的,其中Admin队列的Base Address在Bar空间的控制寄存器体现,而IO队列的Base Address则在Admin队列通过任务的形式进行定义,相关的Doorbell寄存器需要被Host直接访问,更新队列指针。
linux pcie rescan_pcie驱动开发
linux pcie rescan_pcie驱动开发   注意到SQ/CQ队列均存放于Host侧的DDR,NVMe控制器再通过DMA等方式进行搬运,包括SQ任务定义的数据搬运操作。Host仅仅需要访问上述定义的控制寄存器和Doorbell寄存器,不会直接对设备做大量的读写访问操作。主要原因是,BAR空间属于IO操作,CPU直接访问会有非常大的延时,降低CPU的性能。    结语   基于前文描述的数据传输两大要素,以PCIe接口为例,做一个相对具体的描述,进而再以NVMe设备,看一下实际设备是如何工作的。上文仅仅是对数据传输相关的话题进行探讨,实际设备的数据传输还涉及很多内容,如链路、安全、虚拟化等等,都没有在文中体现。

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/59523.html

(0)
上一篇 2024年 8月 30日
下一篇 2024年 8月 30日

相关推荐

关注微信