MMC数据传输过程中对于不连续的物理空间使用scatterlist来启用DMA操作
MMC作为块设备,它的存储空间,最小单位由struct bio_vec 描述,它代表一段物理地址范围。一次块设备传输请求,会涉及到很多个这样的不连续的物理空间。不连续的物理空间,不能直接使用DMA。
这时,可以利用sg操作,让每个bio_vec结构,对应一个scatterlist结构:在MMC的请求处理函数中,遍历每一request中所有bio_vec结构,对应一个scatterlis结构描述。
相关函数:void sg_init_table(struct scatterlist *sg, unsigned int nents);
在HLOS中有一套子系统管理的框架,包括TZ相关的Secure PIL、RAM dump、Restart通知链和System monitor库等,最重要的是一个subsystem driver。
AP和各子系统共用的有共享内存(驱动为smd)、GPIO以及中断等方式。
subsystem driver监控子系统的手段有:
1)子系统的硬件看门狗上报信息给AP的硬件看门狗,subsystem driver通过这种方式知道某个子系统发生崩溃。
2)子系统通过System monitor上报信息给AP侧的System monitor库。
3)子系统通过SMSM设置AP侧的SMSM对应比特位告知AP。
4)子系统通过GPIO操作通知AP。
5)子系统通过中断通知AP。
共享内存驱动smd初始化过程中,会建立64个通道,其中就包括PROC、SMSM、RPC、DIAG等。通常的做法是,AP和子系统都有独立线程监控共享内存的数据更新。PROC用于实现少量的数据通信,多用于简单的命令控制,如上下电、电压配置等。SMSM用于实现两边的Machine State同步。RPC是高通平台AP和Modem之间通信最常用的通道,有很完整的封装协议,Linux根据两个参数(proc+version)以client的身份可以找 到Modem段的server,请求提供相应服务,同时有完备的request/reply机制,完成数据传输。同理,AP也可以作为server提供给
Modem服务。
高通平台Modem占主导作用,在Application Processor启动初始化时,从Share Memory区读取已经由Modem predeclared的一些数据。Share memory根据功能,分为静态+动态部分,每个部分又分为数个小区,每个区的大小不一,与本区实现的功能相关。Modem会把所有区的 offset+size信息存放在静态去Heapinfo里。Linux通过读取这个Heapinfo区信息,就知道Share memory的布局了。
参考文档:80-na157-31_c
共享内存相关的代码主要包含如下:
相关dtsi文件中会声明类似qcom,smsm-modem、qcom,smsm-wcnss这样的节点。
kernel/msm-3.18/drivers/soc/qcom/smsm_debug.c
kernel/msm-3.18/drivers/soc/qcom/smd_init_dt.c
kernel/msm-3.18/drivers/soc/qcom/smd.c
kernel/msm-3.18/drivers/soc/qcom/bam_dmux_private.h
kernel/msm-3.18/drivers/soc/qcom/smd_private.h
kernel/msm-3.18/include/soc/qcom/smd.h
kernel/msm-3.18/include/soc/qcom/smsm.h
kernel/msm-3.18/drivers/char/msm_smd_pkt.c
kernel/msm-3.18/drivers/soc/qcom/pil-q6v5-mss.c
kernel/msm-3.18/drivers/soc/qcom/bam_dmux.c
kernel/msm-3.18/drivers/soc/qcom/smd_debug.c
kernel/msm-3.18/drivers/soc/qcom/ipc_router_smd_xprt.c
kernel/msm-3.18/drivers/net/wireless/ath/wcn36xx/dxe.c
kernel/msm-3.18/drivers/tty/serial/msm_smd_tty.c