异核通信(2):Mailbox (Qualcomm)
0.基础知识
和 IPCC 紧密联系的 Mailbox(邮箱)框架, Mailbox 是一种驱动架构,它依赖于硬件平台来实现。
Mailbox 的实现分为:
邮箱控制器(Mailbox contoller)负责配置和处理来自 IPCC 外设的消息队列或者中断请求( IRQ),并为负责发送或接收通知消息的邮箱客户端提供一个通用的 API。
邮箱客户端(Mailbox client)负责发送或接收通知消息,它通过邮箱控制器提供的通道来发送或接收通知消息,这个通道就是 IPCC 通道。
邮箱框架的大概工作流程是:① 先注册邮箱控制器; ② 邮箱客户端发送数据前,先申请通道; ③ 客户端发送数据; ④邮箱客户端记录数据; ⑤ 邮箱控制器将底层接收到的数据回调给上层应用; ⑥ 当数据发完时,邮箱控制器通知上层当前数据已经发送完成; ⑦ 邮箱客户端释放通道。
1.代码来源
Linux 下的邮箱控制器,通过dtsi中mailbox的compatilbe中,参考:Kernel 6.6 /kernel/drivers/mailbox/qcom-apcs-ipc-mailbox.c(sm8150)或者qcom-ipcc.c(sa8775p). 它配置和控制 IPCC 外设, 可以提供邮箱服务。
qcom_q6v5_pas.c 是远程处理器平台驱动程序, 它主要处理与远程处理器关联的平台资源(例如寄存器、看门狗、复位、时钟和存储器), 可将对应回调函数注册到 Remoteproc 框架中,还可以通过邮箱框架将通知消息转发到远程处理器。
2.SM8150代码分析
2.1 regmap
这里使用到了regmap技术,可以参考这里面的帖子
https://www.nowcoder.com/discuss/429625316387180544?sourceSSR=users
regmap: 提供通用API,用于访问不同类型的寄存器(SPI/I2C/内存映射寄存器等),减少了驱动程序中重复的寄存器访问代码。
regmap_config结构体: 配置寄存器地址位数/地址之间间隔/寄存器值的位数/寄存器最大值(用来限制寄存器访问的范围)/是否启动快速IO操作(第56行代码)
2.2 probe流程
1.分配内存
2.映射寄存器资源:将硬件设备寄存器映射到系统的内存地址空间,本质还是ioremap函数,方便软件直接读写
https://www.nowcoder.com/discuss/419257270007054336
3.初始化寄存器映射:regmap (简化和统一寄存器访问)
4..获取设备匹配数据/设置寄存器映射和偏移量
5.初始化mailbox channel的标识符
6.配置mailbox controller
7.注册mbox_controller
8.如果有时钟设备,注册
9.设置驱动程序数据(本质就是把数据赋给dev)
2.3 不同平台的使用/ops
不同平台上,采用不同的寄存器偏移量(offset),每个偏移量对应于特定平台的寄存器地址,用于访问/控制硬件。
ops只有发送数据:获取qcom_qpcs_ipc结构体,获取通道的索引,向特定寄存器写入数据
3.SA8775P代码分析
3.1 probe
相比于SM8150的probe流程:
IPCC驱动多注册了中断处理函数,设置中断域
但是并没有时钟设备的注册 / 并且不涉及寄存器映射,regmap的操作
3.2 client ops
qcom_ipcc_mbox_xlate: 遍历已经有的通道,查找是否有匹配的client_id 和 signal_id (中断事件标识符),如果没有就重新分配,随后返回配置好的邮箱通道。
qcom_ipcc_mbox_send_data: 将数据发送到指定邮箱通道:根据client_id 和 signal_id唯一的标识一个中断源或者信号通道,将硬件中断号写入发送ID的寄存器,出发中断信号的发送。(中断信号只是通知接收方有数据处理,上一讲已经讲过数据放在了共享内存)
qcom_ipcc_mbox_shutdown:关闭指定邮箱通道
3.3 controller ops
qcom_ipcc_setup_mbox: 计算需要的mailbox channel数量并分配内存,用于存储邮箱通道信息。初始化邮箱控制器基本属性,并注册
qcom_ipcc_probe: 分配内存/映射资源/获取中断/创建中断域用于管理中断/qcom_ipcc_setup_mbox/注册中断处理函数/将qcom_ipcc和设备关联
qcom_ipcc_mask_irq/qcom_ipcc_unmask_irq: 禁用/启动特定的中断信号
#Linux##嵌入式##C++##内核开发#