|
|
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.