科技行者

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

知识库

知识库 安全导航

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

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

  • 扫一扫
    分享文章到微信

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

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

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

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

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

3 Linux对读写操作8237 DMAC的实现

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

3.1 端口地址和寄存器值的宏定义

Linux用宏MAX_DMA_CHANNELS来表示系统当前的DMA通道个数,如下:

#define MAX_DMA_CHANNELS 8

然后,用宏IO_DMA1_BASE和IO_DMA2_BASE来分别表示两个DMAC在I/O端口空间的端口基地址:

#define IO_DMA1_BASE 0x00 
    /* 8 bit slave DMA, channels 0..3 */
  #define IO_DMA2_BASE 0xC0 
    /* 16 bit master DMA, ch 4(=slave input)..7 */

接下来,Linux定义了DMAC各控制寄存器的端口地址。其中,slave SMAC的各控制寄存器的端口地址定义如下:

#define DMA1_CMD_REG 0x08 /* command register (w) */
#define DMA1_STAT_REG 0x08 /* status register (r) */
#define DMA1_REQ_REG 0x09 /* request register (w) */
#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */
#define DMA1_MODE_REG 0x0B /* mode register (w) */
#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */
#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */
#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */

Master DMAC的各控制寄存器的端口地址定义如下:

#define DMA2_CMD_REG 0xD0 /* command register (w) */
#define DMA2_STAT_REG 0xD0 /* status register (r) */
#define DMA2_REQ_REG 0xD2 /* request register (w) */
#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */
#define DMA2_MODE_REG 0xD6 /* mode register (w) */
#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */
#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */
#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */

8个DMA通道的Address Register的端口地址定义如下:

#define DMA_ADDR_0 0x00 /* DMA address registers */
#define DMA_ADDR_1 0x02
#define DMA_ADDR_2 0x04
#define DMA_ADDR_3 0x06
#define DMA_ADDR_4 0xC0
#define DMA_ADDR_5 0xC4
#define DMA_ADDR_6 0xC8
#define DMA_ADDR_7 0xCC

8个DMA通道的Count Register的端口地址定义如下:

#define DMA_CNT_0 0x01 /* DMA count registers */
#define DMA_CNT_1 0x03
#define DMA_CNT_2 0x05
#define DMA_CNT_3 0x07
#define DMA_CNT_4 0xC2
#define DMA_CNT_5 0xC6
#define DMA_CNT_6 0xCA
#define DMA_CNT_7 0xCE

8个DMA通道的Page Register的端口地址定义如下:

#define DMA_PAGE_0 0x87 /* DMA page registers */
#define DMA_PAGE_1 0x83
#define DMA_PAGE_2 0x81
#define DMA_PAGE_3 0x82
#define DMA_PAGE_5 0x8B
#define DMA_PAGE_6 0x89
#define DMA_PAGE_7 0x8A

Mode Register的几个常用值的定义如下:

#define DMA_MODE_READ 0x44 
  /* I/O to memory, no autoinit, increment, single mode */
  #define DMA_MODE_WRITE 0x48 
  /* memory to I/O, no autoinit, increment, single mode */
  #define DMA_MODE_CASCADE 0xC0 
   /* pass thru DREQ->HRQ, DACK<-HLDA only */
  #define DMA_AUTOINIT 0x10
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

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

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