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