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