1.简介
Stream Table中记录了SMMU转换设备地址所需的信息,比如TTB页表基地址、ASID、VMID、配置信息、内存属性等。SMMU使用StreamID和SubstreamID索引Stream Table。Stream Table由STE表和CD表组成,STE表用于第一阶段和第二阶段地址转换,CD表用于第一阶段地址转换。
2.Stream Numbering
同一个SMMU域里面的设备,每个设备都有一个独立的StreamID,StreamID通常情况下从0开始,位宽由SMMU_IDR1.SIDSIZE决定,最大32bits,对于PCIe设备,使用BDF作为StreamID。
SubstreamID是一个可选的实现,位宽由SMMU_IDR1.SSIDSIZE决定,0为不支持,最大20bits,用于区分同一个设备内不同的数据流,从而使用不同的地址转换配置,比如使用SubstreamID区分同一个DMA控制器的不同通道,对于PCIe设备,SubstreamID和PASID(PASID解决多个进程之间共享单个EP)相等。
3.Stream Table Lookup
SMMU使用StreamID查找Stream table,Stream table由多个STE组成。Stream table有两种格式,第一种是Linear Stream table,第二种是2-level Stream table。
3.1.Linear Stream Table
Linear Stream table由STE数组组成,直接使用StreamID进行索引。初始化的时候,Stream table占用的内存需要一次性分配完成,内存大小为STE size的2^n次方。Linear Stream table不灵活,内存利用率低,只适合设备数量较少的场景。
3.2. 2-level Stream table
2-level Stream table的第一级是一个指针数组,里面保存了STE数组的基地址,第二级是STE数组,可能只有一个STE,也可能有多个STE。在初始化的时候只需要分配第一级的内存,第二级STE内存可以根据使用情况动态分配。第一级Stream table使用StreamID[n:x]索引,第二级Stream table使用StreamID[x-1:0]索引,x由 SMMU_(*_)STRTAB_BASE_CFG .SPLIT决定,SPLIT可以为6bits、8bits、10bits。2-level Stream table更加灵活,提高了内存使用率,适合设备数量较多的场景(通常情况下,StreamIDs数量超过64个,就需要支持2-level Stream table)。SMMU支持的Stream table格式由SMMU_IDR0.ST_LEVEL决定,ST_LEVEL为0时,只支持Linear Stream table,ST_LEVEL为1时,同时支持2-level Stream table和Linear Stream table。
上图的SPLIT为8bits,对应的2级Stream table信息如下表所示,第二级Stream table最大支持256个STE。
StreamID的位宽、SPLIT、第一级Stream table大小、第二级Stream table大小对应关系如下图所示。第一级Stream table每个元素大小占用8字节,第二级Stream table每个元素64字节。
3.3.StreamIDs to Context Descriptors
如下图所示,SMMU首先根据StreamID查找Stream table,找到对应的STE。STE中的S1ContextPt指向第一阶段地址转换的CD,S2TTB指向第二阶段地址转换的页表。CD中TTB0保存了用户态SMMU页表基地址,TTB1保存了内核态SMMU页表基地址。下图中只画出了线性CD表中只有一个CD的情况。需要注意的是CD只用在第一阶段地址转换中。
下图是线性CD表中有多个CD的情况,此时需要利用SubstreamID查找对应的CD。
如下图所示,SMMU除了支持线性CD表,还支持2级CD表。如果使用2级CD表,则STE中的S1ContextPt指向地址保存的是CD表的基地址,此时需要根据SubstreamID进行2级查找,即先根据SubstreamID高bits找到对应的L1 CD ptr,然后再根据SubstreamID低bits找到对应的CD。
CD表的结构和大小由STE.S1Fmt和STE.S1CDMax决定。
参考资料
Arm ® System Memory Management Unit Architecture Specification version 3.