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