SMMU简介
SMMU是MMU的一个子设备,基本原理与MMU一致。所以这里先介绍MMU的作用。
MMU机制
MMU为内存分段管理机制,由于内存在申请释放期间必然造成物理内存的碎片化,进而导致一个进程在申请大段连续内存时会耗费很长时间,并且加重内存碎片化。所以虚拟内存机制应运而生。而MMU就是实现虚拟内存到物理内存映射的机制。
正常应用程序使用的地址为线性地址,转换到物理地址流程如下:
SMMU的差异
两者主要的差异在于,MMU为CPU访问主内存机制,SMMU为外设通过DMA直接访问主内存的机制
相较而言,wifi芯片就是一个非cpu的外设,有些操作可以直接通过DMA转送到主内存进而降低cpu的使用和唤醒。
Dtsi文件
将描述板级硬件信息的内容从Linux分离出来,用一个专属的文件来描述,这个专属文件叫做设备树,文件扩展名.dts。而一个SOC可以做出很多不同的板子,这些板子都有共同的信息,将这些共同的信息提取出来作为一个通用的文件,其他.dts文件直接引用这个通用文件即可,这个通用文件就是.dtsi文件。
以18115为例,采用的配置文件就是”sm8150-v2.dtsi”。
文件语法简介
文件引用:
可以像C语言那样包含其他文件,如下:
#include "sm8150.dtsi"
#include "sm8150-v2-camera.dtsi"
文件格式:
cpus { ------->节点名称
#address-cells = <2>; ------->属性值
#size-cells = <0>;
CPU0: cpu@0 { ------->子节点
device_type = "cpu";
compatible = "arm,armv8";
};
CPU1: cpu@100 {
device_type = "cpu";
compatible = "arm,armv8";
};
......
CPU6: cpu@600 {
device_type = "cpu";
compatible = "arm,armv8";
};
CPU7: cpu@700 {
device_type = "cpu";
compatible = "arm,armv8";
};
cpu-map { ---->子节点
cluster0 { ---->相对上一节点的子节点
}
};
};
属性赋值:
[label:] prooerty-name = value; //有值
[label:]property-name; //没有值
字符串: model = "Qualcomm Technologies, Inc. SM8150 V2";
数字:qcom,msm-id = <339 0x20000>;
文件编译
Dtsi文件通过Makefile编译到boot image中。编译方式和C语言没有太大差别
Dtb文件时在编译期有dtsi文件生成,在makefile中直接导入即可。文件转化过程先不讨论。
Wifi相关配置解读
ipa_smmu_wlan: ipa_smmu_wlan {
compatible = "qcom,ipa-smmu-wlan-cb"; ----> wlan ipa配置,在ipa.c中被解析
iommus = <&apps_smmu 0x521 0x0>; ---->没有查到,应是内存映射相关,或为大小
qcom,additional-mapping = ---->映射地址
/* ipa-uc ram */
<0x1E60000 0x1E60000 0x80000>;
qcom,iommu-dma = "bypass"; --->解除映射,直接访问物理地址。
};
qcom,iommu-dma的几个语义的分析:
static int arm_smmu_setup_default_domain(struct device *dev,
struct iommu_domain *domain)
{
ret = of_property_read_string(np, "qcom,iommu-dma", &str);
if (!strcmp(str, "bypass")) --->解除s1映射
domain, DOMAIN_ATTR_S1_BYPASS, &attr);
else if (!strcmp(str, "fastmap")) ----->根据内核代码和介绍,快速映射是提供了比atomic更加搞笑的转换效率,但是需要总线,时钟,电源管理 Regulator都开启时才会有效。
domain, DOMAIN_ATTR_FAST, &attr);
else if (!strcmp(str, "atomic")) ----> 普通二级映射
domain, DOMAIN_ATTR_ATOMIC, &attr);
else if (!strcmp(str, "disabled")) { --->完全关闭
domain, DOMAIN_ATTR_DYNAMIC, &attr);
val = 0;
domain, DOMAIN_ATTR_CONTEXT_BANK, &val);
}
Qcom驱动smmu使用
映射smmu
hdd_soc_probe ---> 挂载总线成功
hdd_init_qdf_ctx --->初始化qdf context
cds_smmu_mem_map_setup ----> 映射smmu
这里主要是配置domain区域,也就是开启smmu后用于映射的内存区域。此外还设置smmu_s1_enabled为true。
使用smmu
申请dma抵制进行smmu映射
->htt_tx_ipa_uc_wdi_tx_buf_alloc
->qdf_mem_get_dma_addr ----初始化dma地址
->保存dma地址作为映射内存
代码如下:
IPA注册函数指针
ol_txrx_ipa_uc_get_resource
解除map采用直接的办法即可,
->***
SMMU对wifi性能的影响
根据代码实现来看,smmu的存在对wifi的影响主要在以下几个方面
接收
接收数据的流转过程为:rx1->rx2->irq3->rx4。
当fw通过DMA写入大量的数据到内存中后,会通过中断告知host去一次性读取这些数据。避免了每次来几个报文就要进行一次中断操作,提升了系统性能和节电能力。
发送
所以,在发送数据的时候也可以对数据进行先写入和fw共享的内存中,然后通告FW经过DMA去读取数据。
SMMU转换对性能的影响
以上可以知道,smmu是为了将DMA映射的物理内存虚拟为连续内存空间。这样访问时经过转换可以快速获取数据。如果不使用SMMU,那么就会不断地进行内存寻址操作,对访问效率产生了一定的影响。