// Code to support legacy Intel 8237 DMA chip. // // Copyright (C) 2008,2009 Kevin O'Connor // Copyright (C) 2002 MandrakeSoft S.A. // // This file may be distributed under the terms of the GNU LGPLv3 license. #include "util.h" // dma_setup #include "x86.h" // outb #define PORT_DMA_ADDR_2 0x0004 #define PORT_DMA_CNT_2 0x0005 #define PORT_DMA1_MASK_REG 0x000a #define PORT_DMA1_MODE_REG 0x000b #define PORT_DMA1_CLEAR_FF_REG 0x000c #define PORT_DMA1_MASTER_CLEAR 0x000d #define PORT_DMA_PAGE_2 0x0081 #define PORT_DMA2_MASK_REG 0x00d4 #define PORT_DMA2_MODE_REG 0x00d6 #define PORT_DMA2_MASTER_CLEAR 0x00da // Setup the DMA controller for a floppy transfer. int dma_floppy(u32 addr, int count, int isWrite) { // check for 64K boundary overrun u16 end = count - 1; u32 last_addr = addr + end; if ((addr >> 16) != (last_addr >> 16)) return -1; u8 mode_register = 0x46; // single mode, increment, autoinit disable, if (isWrite) mode_register = 0x4a; outb(0x06, PORT_DMA1_MASK_REG); outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop outb(addr, PORT_DMA_ADDR_2); outb(addr>>8, PORT_DMA_ADDR_2); outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop outb(end, PORT_DMA_CNT_2); outb(end>>8, PORT_DMA_CNT_2); // port 0b: DMA-1 Mode Register // transfer type=write, channel 2 outb(mode_register, PORT_DMA1_MODE_REG); // port 81: DMA-1 Page Register, channel 2 outb(addr>>16, PORT_DMA_PAGE_2); outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2 return 0; } // Reset DMA controller void dma_setup(void) { // first reset the DMA controllers outb(0, PORT_DMA1_MASTER_CLEAR); outb(0, PORT_DMA2_MASTER_CLEAR); // then initialize the DMA controllers outb(0xc0, PORT_DMA2_MODE_REG); outb(0x00, PORT_DMA2_MASK_REG); }