blob: 20c9fbb76a31f43f677c97ba7a1017e3fbcaff58 [file] [log] [blame]
Kevin O'Connor7b9f2972013-09-18 21:04:03 -04001// Code to support legacy Intel 8237 DMA chip.
2//
3// Copyright (C) 2008,2009 Kevin O'Connor <kevin@koconnor.net>
4// Copyright (C) 2002 MandrakeSoft S.A.
5//
6// This file may be distributed under the terms of the GNU LGPLv3 license.
7
Kevin O'Connor7b9f2972013-09-18 21:04:03 -04008#include "util.h" // dma_setup
Kevin O'Connor4ade5232013-09-18 21:41:48 -04009#include "x86.h" // outb
10
11#define PORT_DMA_ADDR_2 0x0004
12#define PORT_DMA_CNT_2 0x0005
13#define PORT_DMA1_MASK_REG 0x000a
14#define PORT_DMA1_MODE_REG 0x000b
15#define PORT_DMA1_CLEAR_FF_REG 0x000c
16#define PORT_DMA1_MASTER_CLEAR 0x000d
17#define PORT_DMA_PAGE_2 0x0081
18#define PORT_DMA2_MASK_REG 0x00d4
19#define PORT_DMA2_MODE_REG 0x00d6
20#define PORT_DMA2_MASTER_CLEAR 0x00da
Kevin O'Connor7b9f2972013-09-18 21:04:03 -040021
22// Setup the DMA controller for a floppy transfer.
23int
24dma_floppy(u32 addr, int count, int isWrite)
25{
26 // check for 64K boundary overrun
27 u16 end = count - 1;
28 u32 last_addr = addr + end;
29 if ((addr >> 16) != (last_addr >> 16))
30 return -1;
31
32 u8 mode_register = 0x46; // single mode, increment, autoinit disable,
33 if (isWrite)
34 mode_register = 0x4a;
35
36 outb(0x06, PORT_DMA1_MASK_REG);
37 outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop
38 outb(addr, PORT_DMA_ADDR_2);
39 outb(addr>>8, PORT_DMA_ADDR_2);
40 outb(0x00, PORT_DMA1_CLEAR_FF_REG); // clear flip-flop
41 outb(end, PORT_DMA_CNT_2);
42 outb(end>>8, PORT_DMA_CNT_2);
43
44 // port 0b: DMA-1 Mode Register
45 // transfer type=write, channel 2
46 outb(mode_register, PORT_DMA1_MODE_REG);
47
48 // port 81: DMA-1 Page Register, channel 2
49 outb(addr>>16, PORT_DMA_PAGE_2);
50
51 outb(0x02, PORT_DMA1_MASK_REG); // unmask channel 2
52
53 return 0;
54}
55
56// Reset DMA controller
57void
58dma_setup(void)
59{
60 // first reset the DMA controllers
61 outb(0, PORT_DMA1_MASTER_CLEAR);
62 outb(0, PORT_DMA2_MASTER_CLEAR);
63
64 // then initialize the DMA controllers
65 outb(0xc0, PORT_DMA2_MODE_REG);
66 outb(0x00, PORT_DMA2_MASK_REG);
67}