IOMMU Client设备DMA配置过程分析(九)

1.设备树

cp0_pcie0是一个PCIe RC控制器,使用SMMU将PCIe设备的IOVA转换成物理地址,使用iommu-map-maskiommu-map定义PCIe设备使用的Stream ID。设备树定义如下所示。

[arch/arm64/boot/dts/marvell/armada-ap80x.dtsi]
smmu: iommu@100000 {compatible = "marvell,ap806-smmu-500", "arm,mmu-500";reg = <0x100000 0x100000>;dma-coherent;#iommu-cells = <1>;#global-interrupts = <1>;interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,<GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;status = "disabled";
};[arch/arm64/boot/dts/marvell]
&cp0_pcie0 {// iommu-map四个元素分别为BDF、引用的SMMUphandle_node、Base StreamID、数量iommu-map =<0x0   &smmu 0x480 0x20>,<0x100 &smmu 0x4a0 0x20>,<0x200 &smmu 0x4c0 0x20>;iommu-map-mask = <0x031f>;
};

2.dma_configure

设备总系类型数据结构bus_type中定义了dma_configure和dma_cleanup两个回调函数,前者用于建立该总线上设备的DMA配置,后者用于清理该总线上设备的DMA配置。

[include/linux/device/bus.h]
struct bus_type {......int (*dma_configure)(struct device *dev);void (*dma_cleanup)(struct device *dev);......
};

当设备或者驱动初始化的时候都会调用到really_probe函数。若设备所属总线定义了dma_configure函数,则会调用该回调函数建立设备的DMA配置。

[drivers/pci/pci-driver.c]
const struct bus_type pci_bus_type = {.name              = "pci",.match             = pci_bus_match,.uevent            = pci_uevent,.probe             = pci_device_probe,.remove            = pci_device_remove,.shutdown          = pci_device_shutdown,.dev_groups        = pci_dev_groups,.bus_groups        = pci_bus_groups,.drv_groups        = pci_drv_groups,.pm                = PCI_PM_OPS_PTR,.num_vf            = pci_bus_num_vf,.dma_configure     = pci_dma_configure,.dma_cleanup       = pci_dma_cleanup,
};
[drivers/base/platform.c]
const struct bus_type platform_bus_type = {.name              = "platform",.dev_groups        = platform_dev_groups,.match             = platform_match,.uevent            = platform_uevent,.probe             = platform_probe,.remove            = platform_remove,.shutdown          = platform_shutdown,.dma_configure     = platform_dma_configure,.dma_cleanup       = platform_dma_cleanup,.pm                = &platform_dev_pm_ops,
};

3. DMA配置过程

下面以PCIe设备为例,介绍PCIe设备初始化的时候,DMA配置流程。具体工作如下:

  1. platform_bus_type定义了pci_dma_configure函数,因此在really_probe函数里面会调用该函数设置DMA相关配置。
  2. 首先解析"dma-range"属性,"dma-range"属性定义了PCI地址到CPU地址的转换关系(inbound memory)。
  3. 使能ACS。
  4. 解析"iommu-map""iommu-map-mask"属性,然后将PCIe设备的BDF转换成对应的StreamID。
  5. 调用SMMU驱动提供的arm_smmu_of_xlate函数,将转换后的StreamID保存到iommu_fwspec数据结构中。
  6. 调用iommu_probe_device初始化设备,这部分内容在ARM SMMUv3控制器注册过程分析(八)介绍过,这里不多赘述。

DMA配置过程

of_map_id函数首先解析"iommu-map""iommu-map-mask"属性,然后将设备的BDF转换成StreamID。流程如代码所示。

int of_map_id(struct device_node *np, u32 id,const char *map_name, const char *map_mask_name,struct device_node **target, u32 *id_out)
{// 读取"iommu-map"属性map = of_get_property(np, map_name, &map_len);....../* The default is to select all bits. */map_mask = 0xffffffff;// 读取"iommu-map-mask"属性if (map_mask_name)of_property_read_u32(np, map_mask_name, &map_mask);// iommu-map-mask & BDF,通常情况下,只屏蔽function三位masked_id = map_mask & id;// 遍历所有iommu-map定义的数据for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) {struct device_node *phandle_node;u32 id_base = be32_to_cpup(map + 0);  // 解析BDFu32 phandle = be32_to_cpup(map + 1);  // 解析引用的SMMU的phandle_nodeu32 out_base = be32_to_cpup(map + 2); // Base StreamIDu32 id_len = be32_to_cpup(map + 3);   // 长度......// *id_ou = iommu-map-mask & BDF - BDF + Base StreamIDif (id_out)*id_out = masked_id - id_base + out_base;return 0;}/* Bypasses translation */if (id_out)*id_out = id;return 0;
}

参考资料

  1. linux 6.12.35 source code.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/917182.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/917182.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用node-cron实现Node.js定时任务

1. 简介 node-cron 是一个轻量级的Node.js库&#xff0c;用于在指定时间或间隔执行任务。它是Unix系统cron工具的JavaScript实现&#xff0c;适用于需要定时执行脚本的场景&#xff08;如数据备份、定期爬虫等&#xff09;。 2. 安装 npm install node-cron # 或 yarn add node…

前缀和-525.连续数组-力扣(LeetCode)

一、题目解析1、只包含0、1的二进制数组2、找到含有相同数量的0和1&#xff0c;并返回其子数组长度二、算法原理解法1&#xff1a;暴力枚举 时间复杂度O(N^2)解法2&#xff1a;前缀和哈希表对于统计子数组中的0和1的数量有点困难&#xff0c;我们可以将其转化一下转化&#xff…

汽车电子控制系统开发的整体安全理念

1. 摘要在汽车制造商和一级供应商避免责任的背景下&#xff0c;公认的技术规则作为法律要求的标准具有重要的实际意义。道路车辆电子控制单元的安全性目前主要通过 ISO 26262 的要求和流程来保障。特别是随着道路交通自动化程度的不断提高以及现代车辆随之而来的复杂性&#xf…

IDEA重新安装常用设置

IDEA重新安装常用设置 展示固定导航栏 项目构建和运行操作委托给maven 参考&#xff1a;IDEA build委托到Maven build

微服务的编程测评系统9-竞赛新增-竞赛编辑

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言1. 竞赛新增1.1 竞赛基本信息增加-后端开发1.2 竞赛新增题目-后端1.3 竞赛基本信息-前端1.4 竞赛新增题目-前端2. 竞赛编辑2.1 竞赛详情-后端2.2 竞赛详情-前端2…

《零基础入门AI:线性回归进阶(梯度下降算法详解)》

在上一篇博客中&#xff0c;我们学习了线性回归的基本概念、损失函数&#xff08;如MSE&#xff09;以及最小二乘法。最小二乘法通过求解解析解&#xff08;直接计算出最优参数&#xff09;的方式得到线性回归模型&#xff0c;但它有一个明显的局限&#xff1a;当特征数量很多时…

基于C语言实现的KV存储引擎(一)

基于C语言实现的KV存储引擎项目简介整体架构网络模块的实现recatorproactorNtyco项目简介 本文主要是基于 C 语言来实现一个简单的 KV 存储架构&#xff0c;目的就是将网络模块跟实际开发结合起来。 首先我们知道对于数据的存储可以分为两种方式&#xff0c;一种是在内存中进…

c++和python联合编程示例

安装 C与 Python 绑定工具 pip install pybind11这其实相当于使用 python 安装了一个 c的库 pybind11,这个库只由头文件构成&#xff0c; 支持基础数据类型传递以及 python 的 numpy 和 c的 eigen 库之间的自动转换。 编写 CMakeList.txt cmake_minimum_required(VERSION 3.14)…

【OD机试题解法笔记】贪心歌手

题目描述 一个歌手准备从A城去B城参加演出。 按照合同&#xff0c;他必须在 T 天内赶到歌手途经 N 座城市歌手不能往回走每两座城市之间需要的天数都可以提前获知。歌手在每座城市都可以在路边卖唱赚钱。 经过调研&#xff0c;歌手提前获知了每座城市卖唱的收入预期&#xff1a…

AI: 告别过时信息, 用RAG和一份PDF 为LLM打造一个随需更新的“外脑”

嘿&#xff0c;各位技术同学&#xff01;今天&#xff0c;我们来聊一个大家在使用大语言模型&#xff08;LLM&#xff09;时都会遇到的痛点&#xff1a;知识过时。 无论是像我一样&#xff0c;用 Gemini Pro 学习日新月异的以太坊&#xff0c;还是希望它能精确掌握某个特定工具…

深度学习(鱼书)day08--误差反向传播(后三节)

深度学习&#xff08;鱼书&#xff09;day08–误差反向传播&#xff08;后三节&#xff09;一、激活函数层的实现 这里&#xff0c;我们把构成神经网络的层实现为一个类。先来实现激活函数的ReLU层和Sigmoid层。ReLU层 激活函数ReLU&#xff08;Rectified Linear Unit&#xff…

C# 中生成随机数的常用方法

1. 使用 Random 类&#xff08;简单场景&#xff09; 2. 使用 RandomNumberGenerator 类&#xff08;安全场景&#xff09; 3. 生成指定精度的随机小数 C# 中生成随机数的常用方法&#xff1a; 随机数类型实现方式示例代码特点与适用场景随机整数&#xff08;无范围&#xf…

Flink 算子链设计和源代码实现

1、JobGraph &#xff08;JobManager&#xff09; JobGraph 生成时&#xff0c;通过 ChainingStrategy 连接算子&#xff0c;最终在 Task 中生成 ChainedDriver 链表。StreamingJobGraphGeneratorcreateJobGraph() 构建jobGrapch 包含 JobVertex setChaining() 构建算子链isCha…

对接八大应用渠道

背景最近公司想把游戏包上到各个渠道上&#xff0c;因此需要对接各种渠道&#xff0c;渠道如下&#xff0c;oppo、vivo、华为、小米、应用宝、taptap、荣耀、三星等应用渠道 主要就是对接登录、支付接口&#xff08;后续不知道会不会有其他的&#xff09;&#x…

学习:入门uniapp Vue3组合式API版本(17)

42.打包发行微信小程序的上线全流程 域名 配置 发行 绑定手机号 上传 提交后等待&#xff0c;上传 43.打包H5并发布上线到unicloud的前端页面托管 完善配置 unicloud 手机号实名信息不一致&#xff1a;请确保手机号的实名信息与开发者姓名、身份证号一致&#xff0c;请前往开…

SOLIDWORKS材料明细表设置,属于自己的BOM表模板

上一期我们了解了如何在SOLIDWORKS工程图中添加材料明细表?接下来&#xff0c;我们将进行对SOLIDWORKS材料明细表的设置、查看缩略图、模板保存的深度讲解。01 材料明细表设置菜单栏生成表格后左侧菜单栏会显示关于材料明细表的相关设置信息。我们先了解一下菜单栏设置详情&am…

全栈:Maven的作用是什么?本地仓库,私服还有中央仓库的区别?Maven和pom.xml配置文件的关系是什么?

Maven和pom.xml配置文件的关系是什么&#xff1a; Maven是一个构建工具和依赖管理工具&#xff0c;而pom.xml&#xff08;Project Object Model&#xff09;是Maven的核心配置文件。 SSM 框架的项目不一定是 Maven 项目&#xff0c;但推荐使用 Maven进行管理。 SSM 框架的项目可…

超越 ChatGPT:智能体崛起,开启全自主 AI 时代

引言 短短三年,生成式 AI 已从对话助手跨越到能自主规划并完成任务的“智能体(Agentic AI)”时代。这场演进不仅体现在模型规模的提升,更在于系统架构、交互范式与安全治理的全面革新。本文按时间线梳理关键阶段与核心技术,为您呈现 AI 智能体革命的脉络与未来趋势。 1. …

一杯就够:让大脑瞬间在线、让肌肉满电的 “Kick-out Drink” 全解析

一杯就够&#xff1a;让大脑瞬间在线、让肌肉满电的 “Kick-out Drink” 全解析“每天清晨&#xff0c;当闹钟还在哀嚎&#xff0c;你举杯一饮&#xff0c;睡意像被扔出擂台——这&#xff0c;就是 Kick-out Drink 的全部浪漫。”清晨 30 分钟后&#xff0c;250 mL 常温水里溶解…

系统开机时自动执行指令

使用 systemd 创建一个服务单元可以让系统开机时自动执行指令&#xff0c;假设需要执行的指令如下&#xff0c;运行可执行文件&#xff08;/home/demo/可执行文件&#xff09;&#xff0c;并输入参数&#xff08;–input/home/config/demo.yaml&#xff09;&#xff1a; /home/…