Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / seabios / src / hw / dma.c
1 // 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
8 #include "util.h" // dma_setup
9 #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
21
22 // Setup the DMA controller for a floppy transfer.
23 int
24 dma_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
57 void
58 dma_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 }