上篇文章说到枚举过程中的资源分配,这篇文章具体说下。
首先要知道需要分配哪些资源,主要就2个:总线(bus)资源和内存(memory)资源。
总线资源:
Bus资源就是给设备分配唯一的ID,其中bus号为8个bit,所以bus范围为0-255,device是5个bit,所以范围是0-31,function是3个bit,所以范围是0-7,每个设备都要有bus号,同一个bus号,有不同的device,基本都是switch下行口才有,而同一个bus号,同一个device号,不同的function号,是指这个PCIe设备是一个Multi-Function设备,比如有多个网口的网卡可能是这样的。
内存资源:
关于这里分配的memory资源,这个memory资源和PCIe的几个空间(配置空间,IO空间,memory空间,message空间)里面的memory空间是不太一样的。这里分配的memory资源是给设备BAR使用,BAR空间一般都是一个PCIe设备功能使用需要的,比如NVMe设备的BAR0映射的其实就是NVMe Controller相关的寄存器。
看Root Port和PCIe Switch设备的寄存器,可以看到关于资源都有一个范围,比如I/O behind,Memory behind,越靠近根端口的资源范围越大,这是一个很明显的道理,这个根端口下面所有的设备资源都应该包含在根端口下面,而下面的switch自己本身占用了一定资源后,剩余的资源才继续分配给下面,每个设备占用的资源都是不能冲突的,不然两个设备用同一块内存,岂不乱套了,而且基于这个设计,前面说过的TLP报文路由方式就可以通过地址路由了。设备需要的bar空间大小,是通过往bar寄存器写全f,然后PCIe设备把大小填到BAR寄存器里面,软件再读取bar寄存器就知道要给这个设备的BAR空间分配多少资源了。
资源分配这一块,在热插拔流程中体现更明显。因为下面的设备可以替换,每个设备需要的资源大小不一样,移除后资源该怎么处理,接入后再怎么分配,这些都是支持热插拔的主板系统应该考虑的问题。