|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) 1992 NeXT Computer, Inc.
27: *
28: * dma_inline.h -- Inlines for DMA controller access.
29: *
30: * HISTORY
31: * 08 Jan 1993 David Somayajulu at NeXT
32: * fixed dma_set_chan_addr, and dma_set_chan_count
33: * added code for keeping track of status register state
34: *
35: * 13 July 1992 ? at NeXT
36: * Created.
37: */
38:
39: #import <mach/mach_types.h>
40:
41: #import <machdep/i386/io_inline.h>
42:
43: #import <machdep/i386/dma.h>
44: #import <machdep/i386/dma_internal.h>
45: #import <bsd/i386/param.h>
46:
47: #define DMA_DEBUG 0
48:
49: #if DMA_DEBUG
50: #define dprintf(x) printf x;
51: #else /* DMA_DEBUG */
52: #define dprintf(x)
53: #endif /* DMA_DEBUG */
54:
55: /*
56: * Required delay before inb/out to/from 8237.
57: */
58: #define DMA_DELAY DELAY(1)
59:
60: #if !DMA_DEBUG
61: static inline
62: #endif
63: void
64: dma_master_reset(
65: void
66: )
67: {
68: DMA_DELAY;
69: outb(DMA_CHIP_PORT(0, master_reset), 0);
70: DMA_DELAY;
71: outb(DMA_CHIP_PORT(4, master_reset), 0);
72: }
73:
74:
75: #if !DMA_DEBUG
76: static inline
77: #endif
78: void
79: dma_set_cmd(
80: int chip_num,
81: dma_cmd_reg_t reg
82: )
83: {
84: union {
85: dma_cmd_reg_t reg;
86: unsigned char data;
87: } tconv;
88:
89: tconv.reg = reg;
90: DMA_DELAY;
91: if(chip_num) {
92: outb(DMA_CHIP_PORT(4, cmd_status), tconv.data);
93: }
94: else {
95: outb(DMA_CHIP_PORT(0, cmd_status), tconv.data);
96: }
97: }
98:
99: #define ENABLE_DISABLE 1
100:
101: extern dma_cmd_reg_t dma_cmd_regs[DMA_NCHIPS];
102:
103: static inline
104: void
105: dma_chip_enable(
106: int chan
107: )
108: {
109: int chip = (chan > 3 ? 1 : 0);
110:
111: if(!ENABLE_DISABLE)
112: return;
113: dma_cmd_regs[chip].chip_disbl = 0;
114: dma_set_cmd(chip, dma_cmd_regs[chip]);
115: }
116:
117: static inline
118: void
119: dma_chip_disable(
120: int chan
121: )
122: {
123: int chip = (chan > 3 ? 1 : 0);
124:
125: if(!ENABLE_DISABLE)
126: return;
127: dma_cmd_regs[chip].chip_disbl = 1;
128: dma_set_cmd(chip, dma_cmd_regs[chip]);
129: }
130:
131:
132: #if !DMA_DEBUG
133: static inline
134: #endif
135: void
136: dma_set_chan_mask(
137: int chan,
138: dma_mask_reg_t reg
139: )
140: {
141: union {
142: dma_mask_reg_t reg;
143: unsigned char data;
144: } tconv;
145:
146: tconv.reg = reg;
147: dma_chip_disable(chan);
148: DMA_DELAY;
149: outb(DMA_CHIP_PORT(chan, mask), tconv.data);
150: dma_chip_enable(chan);
151: }
152:
153: #if !DMA_DEBUG
154: static inline
155: #endif
156: void
157: dma_set_chan_mode(
158: int chan,
159: dma_mode_reg_t reg
160: )
161: {
162: union {
163: dma_mode_reg_t reg;
164: unsigned char data;
165: } tconv;
166:
167: tconv.reg = reg;
168:
169: dma_chip_disable(chan);
170: DMA_DELAY;
171: outb(DMA_CHIP_PORT(chan, mode), tconv.data);
172: dma_chip_enable(chan);
173: }
174:
175: #if !DMA_DEBUG
176: static inline
177: #endif
178: void
179: dma_set_chan_extend_mode(
180: int chan,
181: dma_extend_mode_reg_t reg
182: )
183: {
184: union {
185: dma_extend_mode_reg_t reg;
186: unsigned char data;
187: } tconv;
188:
189: tconv.reg = reg;
190:
191: dma_chip_disable(chan);
192: DMA_DELAY;
193: outb(DMA_CHIP_PORT(chan, extend_mode), tconv.data);
194: dma_chip_enable(chan);
195: }
196:
197: #if !DMA_DEBUG
198: static inline
199: #endif
200: void
201: dma_set_chan_addr(
202: int chan,
203: vm_offset_t addr
204: )
205: {
206: union {
207: vm_offset_t addr;
208: struct {
209: vm_offset_t addr_byte0 :8,
210: addr_byte1 :8,
211: page :8,
212: hipage :8;
213: } data;
214: struct {
215: vm_offset_t addr :16,
216: page :8,
217: hipage :8;
218: } isa_data;
219:
220: } tconv;
221:
222: tconv.addr = addr;
223: if (dma_write_regs[chan].extend_mode.xfer_width ==
224: DMA_XFR_16_BIT_WORD) {
225: tconv.isa_data.addr >>= 1;
226: }
227: dma_chip_disable(chan);
228:
229: DMA_DELAY;
230: outb(DMA_CHIP_PORT(chan, clear_ff), 0xFF);
231: /* write some crap into this */
232: dprintf(("writing to port =0x%x value = 0x%x\n",
233: DMA_CHAN_PORT(chan, addr), tconv.data.addr_byte0));
234: DMA_DELAY;
235: outb(DMA_CHAN_PORT(chan, addr), tconv.data.addr_byte0);
236:
237: dprintf(("writing to port =0x%x value = 0x%x\n",
238: DMA_CHAN_PORT(chan, addr), tconv.data.addr_byte1));
239: DMA_DELAY;
240: outb(DMA_CHAN_PORT(chan, addr), tconv.data.addr_byte1);
241:
242: dprintf(("writing to port =0x%x value = 0x%x\n",
243: DMA_CHAN_PORT(chan, page), tconv.data.page));
244:
245: DMA_DELAY;
246: outb(DMA_CHAN_PORT(chan, page), tconv.data.page);
247: if (eisa_present()){
248: dprintf(("writing to port =0x%x value = 0x%x\n",
249: DMA_CHAN_PORT(chan, hipage), tconv.data.hipage));
250:
251: // write the hipage address register last so that if we
252: // have an 82357 or its compatible on an ISA machine
253: // nothing bad happens
254:
255: DMA_DELAY;
256: outb(DMA_CHAN_PORT(chan, hipage), tconv.data.hipage);
257: }
258: dma_chip_enable(chan);
259: }
260:
261: #if !DMA_DEBUG
262: static inline
263: #endif
264: void
265: dma_set_chan_count(
266: int chan,
267: vm_size_t count
268: )
269: {
270: union {
271: vm_size_t count;
272: struct {
273: vm_size_t count_byte0 :8,
274: count_byte1 :8,
275: hicount :8,
276: :8;
277: } data;
278: } tconv;
279:
280: if (dma_write_regs[chan].extend_mode.xfer_width ==
281: DMA_XFR_16_BIT_WORD) {
282: tconv.count = (count >> 1) - 1;
283: } else {
284: tconv.count = count - 1;
285: }
286:
287: dma_chip_disable(chan);
288: DMA_DELAY;
289: outb(DMA_CHIP_PORT(chan, clear_ff), 0xFF);
290: /* write some crap into this */
291:
292: dprintf(("writing to port =0x%x value = 0x%x\n",
293: DMA_CHAN_PORT(chan, count), tconv.data.count_byte0));
294:
295: DMA_DELAY;
296: outb(DMA_CHAN_PORT(chan, count), tconv.data.count_byte0);
297:
298: dprintf(("writing to port =0x%x value = 0x%x\n",
299: DMA_CHAN_PORT(chan, count), tconv.data.count_byte1));
300:
301: DMA_DELAY;
302: outb(DMA_CHAN_PORT(chan, count), tconv.data.count_byte1);
303: if (eisa_present()){
304: // write the hicount register first so that if we have an
305: // 82357 or its compatible on an ISA machine nothing bad
306: // happens
307: dprintf(("writing to port =0x%x value = 0x%x\n",
308: DMA_CHAN_PORT(chan, hicount), tconv.data.hicount));
309:
310: DMA_DELAY;
311: outb(DMA_CHAN_PORT(chan, hicount), tconv.data.hicount);
312: }
313:
314: dma_chip_enable(chan);
315:
316: }
317:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.