Home PCIe 配置空间读写机制
Post
Cancel

PCIe 配置空间读写机制

需要特别注意的是,PCIe的Spec中明确规定只有Root有权限发起配置请求(Originate Configuration Requests), 也就是说PCIe系统里面的其他设备是不允许去配置其他设备的配置空间的,即peer-to-peer的配置请求是不允许的。 并且配置请求的路由(Routing)方式只能是采用BDF(Bus,Device,Function)

处理器一般不能够直接发起配置读写请求,因为其只能产生Memory Request和IO Request。这就意味着Root必须要将处理器的相关请求转换为配置读写请求。 针对传统的PCI设备(Legacy PCI),采用的是IO间接寻址访问(IO-indirect Accesses);针对PCIe设备,采用的是Memory-Mapped Accesses。

前面的文章还介绍过,Root和Switch的每一个端口中都包含一个P2P桥,并且知道桥的配置空间头(Configuration Space Header)是Type1型的。如下图所示:

PCIeConfigHeader

每个Type1型的Header中都包含最后一级总线号(Subordinate Bus Number)、下一级总线号(Secondary Bus Number)和上一级总线号(Primary Bus Number)等信息。 当配置请求进行BDF路由的时候,正是依靠这些信息来确定要找的设备的。一个简单地例子如下图所示:

PCIeConfigExample

注:上面的例子是整个PCIe总线系统中只有一个Root的情况,实际上PCIe Spec还允许总线系统中存在多个Root(即Multi-Root)

有两种类型的配置空间,Type0和Type1,分别对应非桥设备(Endpoint)和桥设备(Root和Switch端口中的P2P桥)。

Type0还是Type1是由事务层包(TLP)包头中的Type Field所决定的,而读还是写则是由TLP包头中的Format Field所决定的。分别以下两张图所示:

PCIeConfigType

PCIeConfigRw

PCIe中只有Root才可以发起配置空间读写请求,并且我们知道Root的每个端口中都包含有一个P2P桥。 当Root发起配置空间读写请求时,相应的桥首先检查请求的BDF中的Bus号是否与自己的下一级总线号(Secondary Bus Number)相等, 如果相等,则先将Type1转换为Type0,然后发给下一级(即Endpoint)。 如果不相等,但是在自己的下一级总线号(Secondary Bus Number)和最后一级总线号(Subordinate Bus Number)之间, 则直接将Type1型请求发送给下一级。如果还是不相等,则该桥认为这一请求和自己没什么关系,则忽略该请求。

注:Root最先发送的配置请求一定是Type1型的。非桥设备(Endpoint)会直接忽略Type1型的配置请求。

一个简单的例子如下图所示:

PCIeConfigExample2

This post is licensed under CC BY 4.0 by the author.

PCIe BDF和配置空间

查看linux内核版本信息