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