|
|
1.1 root 1: /* $Header: /kernel/kersrc/i286/RCS/dmac.c,v 1.1 92/07/17 15:21:25 bin Exp Locker: bin $ */
2: /* (lgl-
3: * The information contained herein is a trade secret of Mark Williams
4: * Company, and is confidential information. It is provided under a
5: * license agreement, and may be copied or disclosed only under the
6: * terms of that agreement. Any reproduction or disclosure of this
7: * material without the express written authorization of Mark Williams
8: * Company or persuant to the license agreement is unlawful.
9: *
10: * COHERENT Version 2.3.37
11: * Copyright (c) 1982, 1983, 1984.
12: * An unpublished work by Mark Williams Company, Chicago.
13: * All rights reserved.
14: -lgl) */
15: /*
16: * The routines in this file
17: * deal with the 8237 programmable
18: * DMA controller on the system board.
19: *
20: * $Log: dmac.c,v $
21: * Revision 1.1 92/07/17 15:21:25 bin
22: * Initial revision
23: *
24: * Revision 1.1 88/03/24 09:33:31 src
25: * Initial revision
26: *
27: * 86/12/18 Allan Cornish /usr/src/sys/i8086/ibm_at/dmac.c
28: * Full support for DMA channels 5..7 added.
29: */
30: #include <sys/types.h>
31: #include <sys/dmac.h>
32:
33: /*
34: * This table maps channel
35: * numbers into DMA page address
36: * register ports. The wiring of the
37: * RA lines on the 74LS670 is a bit
38: * strange.
39: */
40: static int dmaport[8] = {
41: DMAPAGE+7, /* 0 (Free) */
42: DMAPAGE+3, /* 1 (Free) */
43: DMAPAGE+1, /* 2 (Floppy) */
44: DMAPAGE+2, /* 3 (Free) */
45: DMAPAGE+15, /* 4 (Cascade) */
46: DMAPAGE+11, /* 5 */
47: DMAPAGE+9, /* 6 */
48: DMAPAGE+10 /* 7 */
49: };
50:
51: /*
52: * Program the channel of the
53: * 8237 DMA controller specified by
54: * "chan". The "paddr" is a 20 bit
55: * physical address. The "count" is
56: * the byte count. The "wflag" is
57: * true if this is a write, from the
58: * point of view of the device.
59: * True return if the mapping can be
60: * set up, given the 64K limits.
61: * The "count" is predecremented, so
62: * that backplane "+T/C" is issued at
63: * the expected point in time.
64: */
65: dmaon(chan, paddr, count, wflag)
66: register int chan;
67: paddr_t paddr;
68: unsigned count;
69: {
70: register int port;
71: register int s;
72:
73: /*
74: * Change from 0 based transfer count to -1 based.
75: */
76: count--;
77:
78: /*
79: * Select byte/word transfer.
80: * Channels 0-4 use byte transfer.
81: * Channels 5-7 use word transfers, with low 17 addr bits right shifted.
82: */
83: if ( chan >= 5 ) {
84: count >>= 1;
85: paddr >>= 1;
86: paddr += (paddr & 0xFF0000L);
87: }
88:
89: /*
90: * Check for DMA straddle.
91: */
92: if ( dmaseg(paddr) != dmaseg(paddr+count) )
93: return (0);
94:
95: s = sphi();
96:
97: /*
98: * Select DMA controller.
99: */
100: if ( chan < 4 ) {
101: port = DMA;
102:
103: /*
104: * Program for dma read/write operation.
105: */
106: if ( wflag != 0 )
107: outb( port + (SETMODE * 1), (chan & 3) | RDMEM );
108: else
109: outb( port + (SETMODE * 1), (chan & 3) | WRMEM );
110: outb( port + (CLEARFL * 1), 0 );
111: }
112: else {
113: port = SDMA;
114:
115: /*
116: * Program for dma read/write operation.
117: */
118: if ( wflag != 0 )
119: outb( SDMA + (SETMODE * 2), (chan & 3) | RDMEM );
120: else
121: outb( SDMA + (SETMODE * 2), (chan & 3) | WRMEM );
122: outb( SDMA + (CLEARFL * 2), 0 );
123: }
124:
125: /*
126: * Select memory bank.
127: */
128: outb( dmaport[chan], (int)(paddr >> 16) );
129:
130: if ( chan < 4 )
131: port += ((chan & 3) << 1);
132: else
133: port += ((chan & 3) << 2);
134:
135: /*
136: * Program memory offset in bank.
137: */
138: outb( port, ((int) paddr) >> 0 );
139: outb( port, ((int) paddr) >> 8 );
140:
141: port++;
142: if ( chan >= 4 )
143: port++;
144:
145: /*
146: * Program transfer count.
147: */
148: outb( port, count >> 0 );
149: outb( port, count >> 8 );
150:
151: spl(s);
152: return (1);
153: }
154:
155: /*
156: * dmago( chan ) - initiate dma transfer
157: */
158: dmago( chan )
159: register int chan;
160: {
161: /*
162: * Enable dma transfers.
163: */
164: if ( chan < 4 )
165: outb( DMA + (SETMASK * 1), (chan & 3) | MASKOFF );
166: else
167: outb( SDMA + (SETMASK * 2), (chan & 3) | MASKOFF );
168: }
169:
170: /*
171: * dmaoff( chan ) - turn dma channel off, return residual count
172: */
173: dmaoff( chan )
174: register int chan;
175: {
176: register int port;
177: register int count;
178: int s;
179:
180: /*
181: * Disable DMA transfers.
182: * Obtain the -1 based residual count.
183: */
184: s = sphi();
185: if ( chan < 4 ) {
186: outb( DMA + (SETMASK * 1), (chan & 3) | MASKON );
187: port = DMA + ((chan & 3) << 1) + 1;
188: }
189: else {
190: outb( SDMA + (SETMASK * 2), (chan & 3) | MASKON );
191: port = SDMA + ((chan & 3) << 2) + 2;
192: }
193: count = inb(port);
194: count += inb(port) << 8;
195: spl( s );
196:
197: /*
198: * Convert residual from -1 based to 0 based.
199: */
200: count++;
201:
202: /*
203: * Convert residual from word based to byte based.
204: */
205: if ( chan >= 5 )
206: count <<= 1;
207:
208: /*
209: * Return residual count in bytes.
210: */
211: return count;
212: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.