Linux环境下DMA的研究与应用---饶兵兵(5)

2019-03-16 19:11

武汉科技大学本科毕业设计

? Suspend Pending ? DMA IDLE

1) DMA引擎在halted状态下完成相关初始化的工作,通过对寄存器CHAINADDR:Descriptor Chain Address Register写入一个值,使DMA通道从halted状态转入到armed状态,而写入CHAINADDR的值往往是第一个硬件描述符的地址,告诉DMA引擎从这里开始数据操作;

2) 在armed状态下,我们通过更新DMACOUNT:DMA descriptor Count register的值,来启动DMA进行传输,当一个描述符完成时,那么DMA引擎里面内部计数器加1,并与DMACOUNT进行比较,如果相等,说明描述符执行完毕,如果不等,则取下一个描述符执行,当然了,在过程1)的初始化过程中,DMA引擎自动清理DMACOUNT和内部计数器值为0;

3) 如果DMA引擎处于Active状态下,我们可以通过向DMA引擎发送Suspend命令而挂起当前DMA通道,进行相关处理。此时DMA执行完所有已经挂起的描述符之后进行suspend pending 状态,如果是在最后一个描述符执行挂起命令,那么DMA引擎进而进入到Halted状态;

4) 当然了,如果DMA正常执行完成所有的描述符,那么DMA从active状态进入到DMA IDLE状态;

5) 我们也可以在DMA IDLE状态下执行挂起命令,使DMA通道进入halted状态; 6) 不管DMA引擎处于何种状态,只要DMA引擎遇到 abort 情况,那么DMA引擎立即进入halted状态,不用去考虑该状态下DMA工作是否已经完成;

7) 通过上图我们可以知道 ,启动DMA引擎有两种方法,第一就是按着正常的流程从halted——armed——active; 还有一种方法就是从DMA IDLE —— active,当然了,这种方式不常用,而在其它状态下更改DMACOUNT的值,对于DMA引擎来说是无效的;

8) 我们只有在active 和DMA IDLE 状态下才能发起挂起命令,否则DMA引擎会遇到一些无法预期的错误,而且发起挂起命令,并不意味着DMA引擎立即被挂起,而是由于其硬件特性,等到所有挂起的描述符执行完毕之后,才被挂起;

3.2.4 I/OAT DMA 数据操作类型

在基描述符中的 Operation Type域指定了I/OAT DMA 对数据处理的操作类型,而对于CB3.2版本的I/OAT 支持以下几种操作类型:

1. Standard DMA Operation:标准的数据拷贝工作; 2. Block Fill:对某指定的数据块按指定的数据进行填充; 3. Move & Generate CRC-32:在数据COPY过程中产生CRC-32; 4. Move &Test CRC-32:在数据COPY过程中检测CRC-32;

17

武汉科技大学本科毕业设计

5. Move and Store CRC-32:在数据COPY过程中存储CRC-32 6. CRC-32 Generation &Test:产生CRC-32并检测; 7. CRC-32 Generation & Store:产生CRC-32并存储;

8. XOR Operation:将多个数据源以字节为单位,按位异或之后送到目标地址; 9. XOR Validate Operation:对多个数据源进行异或之后的结果进行验证操作; 10. XOR with Galois Field Multiply Generate operation:将多个有限域乘积的结果异或之后送到目的地址;

11. XOR with Galois Field Multiply Validate operation:对经过多个有限域乘积之后的异或结果进行验证操作;

目前我们用到最多的是操作类型1、8、9、10、11等。下面我们详细介绍两种功能,一种Standard DMA Operation;另一种是XOR Operation功能。

1) Standard DMA Operation

也就是我们传统意义上的数据拷贝功能,本地内存中的这个点到另一个点或是从本地内存中的这个点到I/O映射内存中的另外一个点,即system memory to system memory and system memory to MMIO。通过一个硬件描述去填充DMAC相关寄存器,告诉DMAC传输数据源的地址、目标的内存的地址以及传输数据的大小等。如果数据源是分散的,或是想将数据源填充到不同的位置时,我们则可以建立一个描述符链,这样就可以完成上面的要求了。不过这里面,对于system memory to MMIO这种类型的拷贝,我们需要注意对于MMIO内存,外设端口都有一个payload的概念,传输数据的大小,不能超过payload所能允许的;

2) XOR Operation

这里,我们以三块数据源为例为说明XOR功能,当然对于I/OAT DMA 最多支持8块数据源进行异或操作。

对于DMAC 取数据源1的第1个字节数据秘数据2的第1个字节数据进行按位异或,然后将得到的结果与数据源3的第1个字节数据再进行就异或,最后将得到的结果送到目标地址的第1个字节处……数据源1的第n个字节与数据源2第n个字节数据进行异或,然后将得到的结果与数据源3的第n个字节数据再进行就异或,最后将得到的结果送到目标地址的第n个字节处,这样依次进行,直到数据传输完毕。之所以引进XOR操作,主要是因为当我数据源1的数据出现无法修复的时候,我们则可以通过其它的数据源和目标数据进行XOR操作,来恢复数据源1的数据。

3.2.5 I/OAT DMA 工作流程

如图3.4所示,是以DMA引擎的状态的转换为线条来描述DMA工作的一般过程: 当DMA引擎处于halted状态时,我们通过软件建立一个描述符链,用来描述当前任务实体;我们将第一个描述符的物理地址写入到CHAINADDR寄存器中,那么此时

18

武汉科技大学本科毕业设计

DMA由halted 状态转入到armed状态;在armed状态下,我们将描述符的个数写入到CHANCOUNT寄存器中,从而启动DMA,使其从armed状态转入到active状态下。DMA在工作过程都会进行错误状态的检测,如果遇到错误或是挂起命令,那么DMA都会发生状态的改变。当然了,对于挂起操作,也需要注意一些条件的,这些在前面已经解释了。

CHAINADDRWrite(Halted)Clear DMACOUNT&Internal desc countCHANCMDWriteARMED StateMore than supported Command setnoyesChancmd errorError bit set In CHANERR?noyesresetChanCmd ErrorSuspend dmaCommand bit?otherignoreyesDMACOUNT=Desc countnoChannel resetState?Fetch the first descriptor specified by CHAINADDR Register &start processingACTIVESuspend pending stateFatal error (abort dma)ARMEDActive stateFetch next descriptor&processFetch next descriptor&processDMACOUNT =Desc countyesnoIdle statenonoDMACOUNT =Desc countExtended descriptorNeeded?yesnoIDLEhaltedstateArmed Or idleFinish operationSuspendPending Or hatledActive or Suspend pendingStop processingStatus = suspend completeStatus = haltedyesDescCountErrorHalted stateHalted stateNO Action

图3.4 IOAT DMA工作流程

19

武汉科技大学本科毕业设计

3.3 Linux环境下I/OAT DMA驱动

3.3.1 DMA engine架构

DMA engine 是DMA操作的抽象层,用于屏蔽各种DMA硬件的差异,给DMA使用者提供统一的调用接口和操作方法。DMA使用者不用关心各种具体的DMA硬件的操作方法,只用使用DMA engine提供的接口来完成DMA操作。DMA engine为各种DMA硬件驱动提供统一的注册接口和操作模版,模版由DMA硬件来填充,并向DMA engine注册,DMA engine通过调用DMA硬件驱动注册的接口来操作DMA硬件。

Linux 2.6.18 (公司正在使用的)内核将各种DMA硬件功能进行抽象,提炼出DMA公共功能形成了屏蔽硬件差异的DMA引擎。现有的DMA功能包括了:数据传输(memcpy)、数据填充(memset)、异或(xor)、PQ等,(jasper芯片支持的CRC功能还没有在驱动和DMA引擎中支持)。这些操作基本上都可视为内存操作。在此基础之上,Linux 2.6.18 内核为屏蔽软件和硬件内存操作的差异,整合了软件内存操作和硬件内存操作,抽象出了异步传输通用借口层(ASYNC_TX)。在有硬件DMA的情况下使用异步内存操作,如果没有硬件则使用同步的软件内存操作。由此形成了屏蔽了各种硬件、屏蔽了软件硬件的内存操作的三层架构。架构如下图所示。

异步传输 async_txXORMEMCPYMEMSETDMAENGINEP+QOTHERIOATIOP软件同步操作硬件异步操作

图3.5 2.6.18内核DMA引擎架构

20

武汉科技大学本科毕业设计

3.3.2 DMA engine数据传输流程

请求有依赖,且依赖的请求的通道具有本请求要求的传输能力NoYes获取依赖请求通道获取一个通道DMA回调调用DMA驱动的操作准备NoYesDMA tasklet依赖请求是否提交DMA中断处理程序Append请求提交请求中断Issue pendding请求

图3.6 DMA engine数据传输流程

1、 DMA通道操作

完成一个任务,需要有一个硬件通道来完成,而对于linux DMA engine 而言,已经在内核中建立了一个功能设备表,将目前所有硬件通道按着基所对应的功能在这个功能设备表上注册,供其它的程序查询申请通道使用,函数如下:

struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type) tx_type是所请求的DMA通道类型。返回获取到的DMA通道实体指针,如果获取失败则返回NULL。

系统存在多个DMA设备时,上面的请求通道的操作是从具有相同能力的通道中遍历,任意选取一个。这样具体返回那个DMA设备提供的通道,调用者是不知道的。但在某些情况下DMA使用者可能只想使用某个特定设备的DMA通道,这样上面的接口就不适合了,DMA engine提供了指定选取特定通道的接口。

struct dma_chan * dma_request_channel (dma_cap_mask_t mask, dma_filter_fn fn, void *fn_param)

mask是能力集掩码,用于指定选取的通道能力;

fn是一个函数指针,该函数由DMA使用者提供,用于DMA通道选择过滤。函数指针原型定义如下:

typedef bool (*dma_filter_fn)(struct dma_chan *chan, void *filter_param)

21


Linux环境下DMA的研究与应用---饶兵兵(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:2017-2018中小学教师素质提升计划范文

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: