nckernel
0.1
Main Page
Related Pages
Modules
Data Structures
Files
File List
Globals
All
Data Structures
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
arch
x86
src
dma.c
Go to the documentation of this file.
1
#include <
sys/types.h
>
2
#include <
sys/io.h
>
3
#include <
stdio.h
>
4
#include <
stddef.h
>
5
6
#include <
dma.h
>
7
#include <
interrupt.h
>
8
9
#include <
list.h
>
10
14
#define DMA_DISABLE(ch) do { \
15
outb(dma_ctrl[(ch)>>2].single_mask, DMA_MASK_DISABLE_CH|(ch)); \
16
} while (0)
17
21
#define DMA_ENABLE(ch) do { \
22
outb(dma_ctrl[(ch)>>2].single_mask, (ch)); \
23
} while (0)
24
28
#define DMA_RESET_PTR(ch) do { \
29
outb(dma_ctrl[(ch) >> 2].byte_ptr, 0x00); \
30
} while (0)
31
37
#define DMA_SET_PAGE(ch, addr) do { \
38
outb(dma_port[ch].page, (((addr) & 0x00FF0000) >> 16)); \
39
} while (0)
40
41
#define DMA_SET_ADDRESS(ch, addr) do { \
42
outb(dma_port[ch].address, ((addr) & 0x000000FF)); \
43
outb(dma_port[ch].address, ((addr) & 0x0000FF00) >> 8); \
44
} while (0)
45
49
#define DMA_SET_MODE(ch, mode) do { \
50
outb(dma_ctrl[(ch)>>2].write_mode, (mode) | (ch)); \
51
} while (0)
52
56
#define DMA_SET_TX_SIZE(ch, cnt) do { \
57
outb(dma_port[ch].count, ((unsigned short)(cnt) & 0x00FF)); \
58
outb(dma_port[ch].count, ((unsigned short)(cnt) & 0xFF00) >> 8); \
59
} while (0)
60
61
#define DMA_CTRL_FROM_CH(ch) (((ch) >> 2) ? DMA_16BIT : DMA_8BIT)
62
63
static
struct
dma_ctrl_port_entry_t
dma_ctrl[
DMA_MAX_TYPE
] = {
64
{
65
.
write_mode
= 0x0B,
66
.single_mask = 0x0A,
67
.byte_ptr = 0x0C,
68
69
.status = 0x08,
70
.command = 0x08,
71
.request = 0x09,
72
.intermediate = 0x0D,
73
.dma_mask = 0x0F,
74
},
75
{
76
.write_mode = 0xD6,
77
.single_mask = 0xD4,
78
.byte_ptr = 0xD8,
79
80
.status = 0xD0,
81
.command = 0xD0,
82
.request = 0xD2,
83
.intermediate = 0xDA,
84
.dma_mask = 0xDE,
85
},
86
};
87
88
static
struct
dma_port_entry_t
dma_port[
DMA_MAX_CHANNEL
] = {
90
{
91
.
page
= 0x87,
92
.address = 0x00,
93
.count = 0x01,
94
},
95
{
96
.page = 0x83,
97
.address = 0x02,
98
.count = 0x03,
99
},
100
{
101
.page = 0x81,
102
.address = 0x04,
103
.count = 0x05,
104
},
105
{
106
.page = 0x82,
107
.address = 0x06,
108
.count = 0x07,
109
},
110
112
{
113
.page = 0x8F,
114
.address = 0xC0,
115
.count = 0xC2,
116
},
117
{
118
.page = 0x8B,
119
.address = 0xC4,
120
.count = 0xC6,
121
},
122
{
123
.page = 0x89,
124
.address = 0xC8,
125
.count = 0xCA,
126
},
127
{
128
.page = 0x8A,
129
.address = 0xCC,
130
.count = 0xCE,
131
},
132
};
133
134
struct
dma_ctrl_port_entry_t
*
dma_get_ctrl_port
(
int
type)
135
{
136
if
(type < 0 || type >=
DMA_MAX_TYPE
) {
137
return
NULL
;
138
}
139
140
return
dma_ctrl + type;
141
}
142
143
struct
dma_port_entry_t
*
dma_get_port
(
int
channel)
144
{
145
if
(channel < 0 || channel >=
DMA_MAX_CHANNEL
) {
146
return
NULL
;
147
}
148
149
return
dma_port + channel;
150
}
151
152
void
dma_init
(
int
ch,
int
mode,
unsigned
long
address
,
int
count
)
153
{
154
unsigned
long
flags;
155
156
irq_local_save
(&flags);
157
DMA_DISABLE
(ch);
158
DMA_RESET_PTR
(ch);
159
160
DMA_SET_ADDRESS
(ch, address);
161
DMA_RESET_PTR
(ch);
162
163
DMA_SET_TX_SIZE
(ch, count - 1);
164
165
DMA_SET_MODE
(ch, mode);
166
DMA_SET_PAGE
(ch, address);
167
168
DMA_ENABLE
(ch);
169
irq_local_restore
(flags);
170
}
171
172
int
dma_is_done
(
int
ch)
173
{
174
unsigned
char
ret;
175
176
ret =
inb
(dma_ctrl[
DMA_CTRL_FROM_CH
(ch)].status);
177
return
(ret & (0x01 << ch)) ? 0 : -1;
178
}
179
180
/* End of a file */
Generated on Thu Nov 7 2013 02:45:25 for nckernel by
1.8.4