~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/seabios/src/hw/dma.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}