1 PCIe系统硬件结构
注意:在pci设备中,可以通过引脚选中设备,但是在PCIe设备中,由于是端对端的配置过程(endpoint to endpoint)。PCIe桥中有很多端口,端口可以直接连接PCIe设备。在设备之间只有差分信号,并无其他引脚。无需选中,每个端口只有一个设备。但是,RC发出的信号在switch中需要选择端口。
配置时如何选中哪个p2p?配置后如何选中p2p?配置后用pci_addr地址范围选中端口就行了。首先,CPU 发出的地址经过RC, 会转换成add_pci。P2P也是一个设备,可以看作是一个桥,也有自己的BDF。RC传过来的地址,会经过每个P2P的判断,判断该地址在不在P2P处理的范围之内(图中,假设了每个P2P的地址范围分别是A-B,C-D,E-F)。
- 那么是谁对P2P设备的地址访问做决定的呢?(谁写进去他的配置空间里),这里也是回答配置时如何选择哪个p2p?
接下来就回答第一个问题,在配置时应该给各个p2p如何配置地址访问,如何选中?
在一开始的时候,host发出的地址肯定知道是自己要去配置还是去读取,他们的信息写在发出fmt和type字段里面(接下来就是要确定访问哪个目标设备,根据下面的TLP header的格式可以知道,确定哪个设备是需要知道Bus, Deveice, Function的)。但是我们一开始,并不知道每个设备的总线号,设备号,功能号,因此后面的字段都是未知的。
但是,由于设备号是在硬件上就写死了的,例如RC后pcie桥的所有p2p桥,会从做到右一次进行编号0,1,2(因此在RC这一层也就是bus0这层,可以根据设备号来选择哪个设备)。
那么我们在最开始时,是如何确定BDF号的呢?首先,RC在制作的时候,在硬件上就对3个P2P写死了设备号,从小到大编号。0,1,2....等(所以这里的设备号又是能确定的?)。这几个设备会监测总线0上的信号,发现传过来的包属于cfgread0或者configread1时,此时就是要进行配置读写。
host桥发出事务层的包TLP时,通过TLP头部格式。如果是读取当前bridge,在事务层中的head有一个head字段,直接配置cfgrd0即可。如果需要经过bridge,则配置cfgrd1。意味着总线上传输的信号包括:Bus Dev Fun和Reg。--没太看懂
2 PCIe系统软件层次
从软件的角度,我们只关心事务层。在事务层传输中,我们需要关心
- 要做什么:内存读、内存写、IO读、IO写、配置读、配置写以及消息总线事务和原子操作等总事务。这相当于事务层的分类。
- 内存读写/io读写:哪个地址?
- 配置读写:哪个“Bus/device/function/register”
- 数据