当前位置: 首页 > news >正文

ARM SMMUv3控制器初始化及设备树分析(七)

1.初始化

SMMUv3驱动的入口函数如下代码所示。

[drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c]
static struct platform_driver arm_smmu_driver = {.driver        = {.name                     = "arm-smmu-v3",.of_match_table           = arm_smmu_of_match,.suppress_bind_attrs      = true,},.probe      = arm_smmu_device_probe,.remove_new = arm_smmu_device_remove,.shutdown   = arm_smmu_device_shutdown,
};

SMMUv3初始化函数的主要工作有:

  1. 解析设备树中的"#iommu-cells""dma-coherent""dma-noncoherent"属性。
  2. 获取中断号
  3. 获取硬件信息。读取ID0、ID1、IDR3、IDR5、IIDR等寄存器,判断硬件是否支持下面的特性:
  4. ID0:是否支持2级表,页表大小端,是否支持PRI、ATS、SEV、MSI,是否支持Hypervisor以及VHE扩展,是否支持HTTU,是否支持STALL模式、是否支持第一阶段和第二阶段地址转换、支持的页表格式、ASID和VMID的位宽。
  5. ID1:判断是否支持固定的流表基地址、固定的队列基地址以及Relative base pointers,若支持其中一个则返回错误(标准驱动不支持embedded SMMU的设计),是否支持内存属性覆盖,命令队列、事件队列、PRI队列的大小,SID和SSID的位宽(iommu.max_pasids = 1UL << smmu->ssid_bits),STRTAB_SPLIT
  6. ID3:是否支持基于范围和层级的TLB Invalidations。
  7. ID5:outstanding stalls的最大数量,页表大小,输入地址的大小,输出地址的大小
  8. IIDR:MMU特性。
  9. 是否支持SVA特性。
  10. 初始化软件数据结构。
  11. 初始化命令队列、事件队列、IO页表缺页异常队列(如果支持SVA和STALL特性)和PRIQ队列。
  12. 根据硬件支持的特性,创建线性表(一次性分配1 << smmu->sid_bits个STE,并将STE设置为ABORT)或者2级流表(只分配第一级L1STD内存,第二级STE内存在arm_smmu_probe_device函数中分配)。
  13. 将保留内存区域的映射设置为bypass,不映射。
  14. 复位SMMU控制器。
  15. 注册SMMU控制器。

SMMU控制器probe流程

2.设备树

2.1.控制器设备树

下面是RK3588定义的SMMUv3的设备树。#iommu-cells属性用于指定编码地址的单元数量。

  • #iommu-cells = <0>:表示IOMMU控制器只有一个master(client)设备,不需要在#iommu-cells指定额外信息。
  • #iommu-cells = <1>:表示IOMMU控制器有多个master设备,需要一个额外的cell提供master设备信息,以便于IOMMU控制器区分master设备。对于SMMU,额外的cell提供StreamID信息。
  • #iommu-cells = <4>:某些IOMMU控制器允许master设备配置DMA窗口。第一个cell提供master设备信息,第二个cell提供DMA窗口的起始地址,第三个和第四个cell提供DMA窗口的长度。SMMU不支持这种情况。
[arch/arm64/boot/dts/rockchip/rk3588-base.dtsi]
mmu600_pcie: iommu@fc900000 {compatible = "arm,smmu-v3";reg = <0x0 0xfc900000 0x0 0x200000>;interrupts = <GIC_SPI 369 IRQ_TYPE_EDGE_RISING 0>,<GIC_SPI 371 IRQ_TYPE_EDGE_RISING 0>,<GIC_SPI 374 IRQ_TYPE_EDGE_RISING 0>,<GIC_SPI 367 IRQ_TYPE_EDGE_RISING 0>;/* eventq: 用于处理 SMMU 的事件队列(Event Queue)中的事件。* gerror: 用于处理 SMMU 的全局错误(Global Error)。* priq: 用于处理 Page Request Interface(PRI)队列中的事件。* cmdq-sync: 用于同步命令队列(Command Queue)的执行。*/interrupt-names = "eventq", "gerror", "priq", "cmdq-sync";/* 的 */#iommu-cells = <1>;status = "disabled";
};

2.2.master设备设备树

下面是两个SMMU master设备的设备树。第一个PCI Host设备通过iommus属性引用smmu,StreamID为0x1,外部可能只会接一个PCIe设备,因此只需要一个StreamID。第二个设备为PCIe RC,外部可能会接很多设备,iommus属性无法描述这种情况,因此需要使用iommu-mapiommu-map-mask属性。

  • iommu-map:将PCIe设备的Requester ID(BDF)映射成IOMMU特有的数据,对于SMMU,则将Requester ID映射成StreamID。格式为iommu-map = <rid-base iommu iommu-base length>。rid-base为Requester ID,iommu为引用的IOMMU设备树节点,iommu-base为StreamID,length为映射的长度。
  • iommu-map-mask:每个Requester ID映射成StreamID之前,都需要先和iommu-map-mask与。该属性的作用是将多个Requester ID映射成一个StreamID,比如多Function的PCIe设备,通常位于一个iommu_domain里面,因此需要屏蔽Function number。
pcie: pcie@20000000 {compatible = "pci-host-ecam-generic";reg = <0x20000000 0x100000>;#address-cells = <3>;#size-cells = <2>;device_type = "pci";bus-range = <0x00 0xff>;ranges = <0x02000000 0x00 0x40000000 0x40000000 0x00 0x40000000>;iommus = <&smmu 0x1>;  // 引用SMMU,使用streamID 1dma-coherent;status = "okay";
};pci: pci@f {reg = <0xf 0x1>;compatible = "vendor,pcie-root-complex";device_type = "pci";/** The sideband data provided to the IOMMU is the RID with the* function bits masked out.*/iommu-map = <0x0 &iommu 0x0 0x10000>;iommu-map-mask = <0xfff8>;
};

参考资料

  1. linux 6.12.35 source code.
  2. Documentatio/devicetree/bindings/pci/pci-iommu.txt.
  3. Documentation/devicetree/bindings/iommu/iommu.txt.
http://www.dtcms.com/a/299297.html

相关文章:

  • Cgroup 控制组学习(一)
  • org.apache.lucene.search.Query#rewrite(IndexSearcher)过时讲解
  • C程序内存布局详解
  • Linux内核设计与实现 - 第14章 块I/O层
  • Aerospike Java客户端核心API实战指南:从基础操作到高级功能全解析
  • JAVA算法题练习day1
  • 迅为RK3568开发板OpeHarmony学习开发手册1.1-内核移植优化
  • Caffeine 缓存库的常用功能使用介绍
  • 端到端测试:确保Web应用程序的完整性和可靠性
  • Spark-TTS 使用
  • CPU 为什么需要缓存?揭开速度与效率的底层逻辑
  • 网安-中间件-Redis未授权访问漏洞
  • Flutter控件归纳总结
  • 解决VSCode中Github Copilot无法登陆的问题
  • 从零开始的云计算生活——第三十六天,山雨欲来,Ansible入门
  • Windows 平台源码部署 Dify教程(不依赖 Docker)
  • 电脑开机后网络连接慢?
  • Rust嵌入式开发实战
  • 垃圾回收算法与垃圾收集器
  • 数字迷雾中的安全锚点:解码匿名化与假名化的法律边界与商业价值
  • 深入解析三大Web安全威胁:文件上传漏洞、SQL注入漏洞与WebShell
  • MySQL 8.0 OCP 1Z0-908 题目解析(37)
  • Qt 异步编程模式与应用
  • LeetCode——1717. 删除子字符串的最大得分
  • JVM参数
  • 7月26日京东秋招第一场第二题
  • sssss
  • python面向对象编程详解
  • 机器学习的工作流程
  • JVM-GC 相关知识