科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Linux系统对ISA总线DMA的实现(中) (2)

Linux系统对ISA总线DMA的实现(中) (2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

由于DMAC的各寄存器是在I/O端口空间中编址的,因此读写8237 DMAC是平台相关的。对于x86平台来说,Linux在include/asm-i386/Dma.h头文件中实现了对两个8237 DMAC的读写操作。

作者:hehyuan 来源:赛迪网技术社区 2007年11月17日

关键字: 操作系统 实现 ISA Linux

  • 评论
  • 分享微博
  • 分享邮件

3.2 读写DMAC的高层接口函数

(1)使能/禁止一个特定的DMA通道

Single Channel Mask Register中的bit[2]为0表示使能一个DMA通道,为1表示禁止一个DMA通道;而该寄存器中的bit[1:0]则用于表示使能或禁止哪一个DMA通道。

函数enable_dma()实现使能某个特定的DMA通道,传输dmanr指定DMA通道号,其取值范围是0~DMA_MAX_CHANNELS-1。如下:

static __inline__ void enable_dma(unsigned int dmanr)
{
if (dmanr<=3)
dma_outb(dmanr, DMA1_MASK_REG);
else
dma_outb(dmanr & 3, DMA2_MASK_REG);
}

宏dma_outb和dma_inb实际上就是outb(或outb_p)和inb函数。注意,当dmanr取值大于3时,对应的是Master DMAC上的DMA通道0~3,因此在写DMA2_MASK_REG之前,要将dmanr与值3进行与操作,以得到它在master DMAC上的局部通道编号。

函数disable_dma()禁止一个特定的DMA通道,其源码如下:

static __inline__ void disable_dma(unsigned int dmanr)
{
if (dmanr<=3)
dma_outb(dmanr | 4, DMA1_MASK_REG);
else
dma_outb((dmanr & 3) | 4, DMA2_MASK_REG);
}

为禁止某个DMA通道,Single Channel Mask Register中的bit[2]应被置为1。

(2)清除Flip-Flop寄存器

函数Clear_dma_ff()实现对slave/Master DMAC的Flip-Flop寄存器进行清零操作。如下:

static __inline__ void clear_dma_ff(unsigned int dmanr)
{
if (dmanr<=3)
dma_outb(0, DMA1_CLEAR_FF_REG);
else
dma_outb(0, DMA2_CLEAR_FF_REG);
}

(3)设置某个特定DMA通道的工作模式

函数set_dma_mode()实现设置一个特定DMA通道的工作模式。如下

static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
{
if (dmanr<=3)
dma_outb(mode | dmanr, DMA1_MODE_REG);
else
dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
}

DMAC 的Mode Register中的bit[1:0]指定对该DMAC上的哪一个DMA通道进行模式设置。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章