1 /* 2 * Copyright (c) 1982, 1990 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)dma.c 7.5 (Berkeley) 5/4/91 34 */ 35 36 /* 37 * DMA driver 38 */ 39 40 #include "param.h" 41 #include "systm.h" 42 #include "time.h" 43 #include "kernel.h" 44 #include "proc.h" 45 46 #include "dmareg.h" 47 #include "dmavar.h" 48 #include "device.h" 49 50 #include "../include/cpu.h" 51 #include "../hp300/isr.h" 52 53 extern void isrlink(); 54 extern void _insque(); 55 extern void _remque(); 56 extern void timeout(); 57 extern u_int kvtop(); 58 extern void PCIA(); 59 60 /* 61 * The largest single request will be MAXPHYS bytes which will require 62 * at most MAXPHYS/NBPG+1 chain elements to describe, i.e. if none of 63 * the buffer pages are physically contiguous (MAXPHYS/NBPG) and the 64 * buffer is not page aligned (+1). 65 */ 66 #define DMAMAXIO (MAXPHYS/NBPG+1) 67 68 struct dma_chain { 69 int dc_count; 70 char *dc_addr; 71 }; 72 73 struct dma_softc { 74 struct dmadevice *sc_hwaddr; 75 struct dmaBdevice *sc_Bhwaddr; 76 char sc_type; 77 char sc_flags; 78 u_short sc_cmd; 79 struct dma_chain *sc_cur; 80 struct dma_chain *sc_last; 81 struct dma_chain sc_chain[DMAMAXIO]; 82 } dma_softc[NDMA]; 83 84 /* types */ 85 #define DMA_B 0 86 #define DMA_C 1 87 88 /* flags */ 89 #define DMAF_PCFLUSH 0x01 90 #define DMAF_VCFLUSH 0x02 91 #define DMAF_NOINTR 0x04 92 93 struct devqueue dmachan[NDMA + 1]; 94 int dmaintr(); 95 96 #ifdef DEBUG 97 int dmadebug = 0; 98 #define DDB_WORD 0x01 /* same as DMAGO_WORD */ 99 #define DDB_LWORD 0x02 /* same as DMAGO_LWORD */ 100 #define DDB_FOLLOW 0x04 101 #define DDB_IO 0x08 102 103 void dmatimeout(); 104 int dmatimo[NDMA]; 105 106 long dmahits[NDMA]; 107 long dmamisses[NDMA]; 108 long dmabyte[NDMA]; 109 long dmaword[NDMA]; 110 long dmalword[NDMA]; 111 #endif 112 113 void 114 dmainit() 115 { 116 register struct dmareg *dma = (struct dmareg *)DMA_BASE; 117 register struct dma_softc *dc; 118 register int i; 119 char rev; 120 121 /* 122 * Determine the DMA type. 123 * Don't know how to easily differentiate the A and B cards, 124 * so we just hope nobody has an A card (A cards will work if 125 * DMAINTLVL is set to 3). 126 */ 127 if (!badbaddr((char *)&dma->dma_id[2])) 128 rev = dma->dma_id[2]; 129 else { 130 rev = 'B'; 131 #if !defined(HP320) 132 panic("dmainit: DMA card requires hp320 support"); 133 #endif 134 } 135 136 dc = &dma_softc[0]; 137 for (i = 0; i < NDMA; i++) { 138 dc->sc_hwaddr = (i & 1) ? &dma->dma_chan1 : &dma->dma_chan0; 139 dc->sc_Bhwaddr = (i & 1) ? &dma->dma_Bchan1 : &dma->dma_Bchan0; 140 dc->sc_type = rev == 'B' ? DMA_B : DMA_C; 141 dc++; 142 dmachan[i].dq_forw = dmachan[i].dq_back = &dmachan[i]; 143 } 144 dmachan[i].dq_forw = dmachan[i].dq_back = &dmachan[i]; 145 #ifdef DEBUG 146 /* make sure timeout is really not needed */ 147 timeout(dmatimeout, 0, 30 * hz); 148 #endif 149 150 printf("dma: 98620%c with 2 channels, %d bit DMA\n", 151 rev, rev == 'B' ? 16 : 32); 152 } 153 154 int 155 dmareq(dq) 156 register struct devqueue *dq; 157 { 158 register int i; 159 register int chan; 160 register int s = splbio(); 161 162 chan = dq->dq_ctlr; 163 i = NDMA; 164 while (--i >= 0) { 165 if ((chan & (1 << i)) == 0) 166 continue; 167 if (dmachan[i].dq_forw != &dmachan[i]) 168 continue; 169 insque(dq, &dmachan[i]); 170 dq->dq_ctlr = i; 171 splx(s); 172 return(1); 173 } 174 insque(dq, dmachan[NDMA].dq_back); 175 splx(s); 176 return(0); 177 } 178 179 void 180 dmafree(dq) 181 register struct devqueue *dq; 182 { 183 int unit = dq->dq_ctlr; 184 register struct dma_softc *dc = &dma_softc[unit]; 185 register struct devqueue *dn; 186 register int chan, s; 187 188 s = splbio(); 189 #ifdef DEBUG 190 dmatimo[unit] = 0; 191 #endif 192 DMA_CLEAR(dc); 193 /* 194 * XXX we may not always go thru the flush code in dmastop() 195 */ 196 #if defined(HP360) || defined(HP370) 197 if (dc->sc_flags & DMAF_PCFLUSH) { 198 PCIA(); 199 dc->sc_flags &= ~DMAF_PCFLUSH; 200 } 201 #endif 202 #if defined(HP320) || defined(HP350) 203 if (dc->sc_flags & DMAF_VCFLUSH) { 204 /* 205 * 320/350s have VACs that may also need flushing. 206 * In our case we only flush the supervisor side 207 * because we know that if we are DMAing to user 208 * space, the physical pages will also be mapped 209 * in kernel space (via vmapbuf) and hence cache- 210 * inhibited by the pmap module due to the multiple 211 * mapping. 212 */ 213 DCIS(); 214 dc->sc_flags &= ~DMAF_VCFLUSH; 215 } 216 #endif 217 remque(dq); 218 chan = 1 << unit; 219 for (dn = dmachan[NDMA].dq_forw; 220 dn != &dmachan[NDMA]; dn = dn->dq_forw) { 221 if (dn->dq_ctlr & chan) { 222 remque((caddr_t)dn); 223 insque((caddr_t)dn, (caddr_t)dq->dq_back); 224 splx(s); 225 dn->dq_ctlr = dq->dq_ctlr; 226 (dn->dq_driver->d_start)(dn->dq_unit); 227 return; 228 } 229 } 230 splx(s); 231 } 232 233 void 234 dmago(unit, addr, count, flags) 235 int unit; 236 register char *addr; 237 register int count; 238 register int flags; 239 { 240 register struct dma_softc *dc = &dma_softc[unit]; 241 register struct dma_chain *dcp; 242 register char *dmaend = NULL; 243 register int tcount; 244 245 if (count > MAXPHYS) 246 panic("dmago: count > MAXPHYS"); 247 #if defined(HP320) 248 if (dc->sc_type == DMA_B && (flags & DMAGO_LWORD)) 249 panic("dmago: no can do 32-bit DMA"); 250 #endif 251 #ifdef DEBUG 252 if (dmadebug & DDB_FOLLOW) 253 printf("dmago(%d, %x, %x, %x)\n", 254 unit, addr, count, flags); 255 if (flags & DMAGO_LWORD) 256 dmalword[unit]++; 257 else if (flags & DMAGO_WORD) 258 dmaword[unit]++; 259 else 260 dmabyte[unit]++; 261 #endif 262 /* 263 * Build the DMA chain 264 */ 265 for (dcp = dc->sc_chain; count > 0; dcp++) { 266 dcp->dc_addr = (char *) kvtop(addr); 267 if (count < (tcount = NBPG - ((int)addr & PGOFSET))) 268 tcount = count; 269 dcp->dc_count = tcount; 270 addr += tcount; 271 count -= tcount; 272 if (flags & DMAGO_LWORD) 273 tcount >>= 2; 274 else if (flags & DMAGO_WORD) 275 tcount >>= 1; 276 if (dcp->dc_addr == dmaend 277 #if defined(HP320) 278 /* only 16-bit count on 98620B */ 279 && (dc->sc_type != DMA_B || 280 (dcp-1)->dc_count + tcount <= 65536) 281 #endif 282 ) { 283 #ifdef DEBUG 284 dmahits[unit]++; 285 #endif 286 dmaend += dcp->dc_count; 287 (--dcp)->dc_count += tcount; 288 } else { 289 #ifdef DEBUG 290 dmamisses[unit]++; 291 #endif 292 dmaend = dcp->dc_addr + dcp->dc_count; 293 dcp->dc_count = tcount; 294 } 295 } 296 dc->sc_cur = dc->sc_chain; 297 dc->sc_last = --dcp; 298 dc->sc_flags = 0; 299 /* 300 * Set up the command word based on flags 301 */ 302 dc->sc_cmd = DMA_ENAB | DMA_IPL(DMAINTLVL) | DMA_START; 303 if ((flags & DMAGO_READ) == 0) 304 dc->sc_cmd |= DMA_WRT; 305 if (flags & DMAGO_LWORD) 306 dc->sc_cmd |= DMA_LWORD; 307 else if (flags & DMAGO_WORD) 308 dc->sc_cmd |= DMA_WORD; 309 if (flags & DMAGO_PRI) 310 dc->sc_cmd |= DMA_PRI; 311 #if defined(HP360) || defined(HP370) 312 /* 313 * Remember if we need to flush external physical cache when 314 * DMA is done. We only do this if we are reading (writing memory). 315 */ 316 if (ectype == EC_PHYS && (flags & DMAGO_READ)) 317 dc->sc_flags |= DMAF_PCFLUSH; 318 #endif 319 #if defined(HP320) || defined(HP350) 320 if (ectype == EC_VIRT && (flags & DMAGO_READ)) 321 dc->sc_flags |= DMAF_VCFLUSH; 322 #endif 323 /* 324 * Remember if we can skip the dma completion interrupt on 325 * the last segment in the chain. 326 */ 327 if (flags & DMAGO_NOINT) { 328 if (dc->sc_cur == dc->sc_last) 329 dc->sc_cmd &= ~DMA_ENAB; 330 else 331 dc->sc_flags |= DMAF_NOINTR; 332 } 333 #ifdef DEBUG 334 if (dmadebug & DDB_IO) 335 if ((dmadebug&DDB_WORD) && (dc->sc_cmd&DMA_WORD) || 336 (dmadebug&DDB_LWORD) && (dc->sc_cmd&DMA_LWORD)) { 337 printf("dmago: cmd %x, flags %x\n", 338 dc->sc_cmd, dc->sc_flags); 339 for (dcp = dc->sc_chain; dcp <= dc->sc_last; dcp++) 340 printf(" %d: %d@%x\n", dcp-dc->sc_chain, 341 dcp->dc_count, dcp->dc_addr); 342 } 343 dmatimo[unit] = 1; 344 #endif 345 DMA_ARM(dc); 346 } 347 348 void 349 dmastop(unit) 350 register int unit; 351 { 352 register struct dma_softc *dc = &dma_softc[unit]; 353 register struct devqueue *dq; 354 355 #ifdef DEBUG 356 if (dmadebug & DDB_FOLLOW) 357 printf("dmastop(%d)\n", unit); 358 dmatimo[unit] = 0; 359 #endif 360 DMA_CLEAR(dc); 361 #if defined(HP360) || defined(HP370) 362 if (dc->sc_flags & DMAF_PCFLUSH) { 363 PCIA(); 364 dc->sc_flags &= ~DMAF_PCFLUSH; 365 } 366 #endif 367 #if defined(HP320) || defined(HP350) 368 if (dc->sc_flags & DMAF_VCFLUSH) { 369 /* 370 * 320/350s have VACs that may also need flushing. 371 * In our case we only flush the supervisor side 372 * because we know that if we are DMAing to user 373 * space, the physical pages will also be mapped 374 * in kernel space (via vmapbuf) and hence cache- 375 * inhibited by the pmap module due to the multiple 376 * mapping. 377 */ 378 DCIS(); 379 dc->sc_flags &= ~DMAF_VCFLUSH; 380 } 381 #endif 382 /* 383 * We may get this interrupt after a device service routine 384 * has freed the dma channel. So, ignore the intr if there's 385 * nothing on the queue. 386 */ 387 dq = dmachan[unit].dq_forw; 388 if (dq != &dmachan[unit]) 389 (dq->dq_driver->d_done)(dq->dq_unit); 390 } 391 392 int 393 dmaintr() 394 { 395 register struct dma_softc *dc; 396 register int i, stat; 397 int found = 0; 398 399 #ifdef DEBUG 400 if (dmadebug & DDB_FOLLOW) 401 printf("dmaintr\n"); 402 #endif 403 for (i = 0, dc = dma_softc; i < NDMA; i++, dc++) { 404 stat = DMA_STAT(dc); 405 if ((stat & DMA_INTR) == 0) 406 continue; 407 found++; 408 #ifdef DEBUG 409 if (dmadebug & DDB_IO) { 410 if ((dmadebug&DDB_WORD) && (dc->sc_cmd&DMA_WORD) || 411 (dmadebug&DDB_LWORD) && (dc->sc_cmd&DMA_LWORD)) 412 printf("dmaintr: unit %d stat %x next %d\n", 413 i, stat, (dc->sc_cur-dc->sc_chain)+1); 414 } 415 if (stat & DMA_ARMED) 416 printf("dma%d: intr when armed\n", i); 417 #endif 418 if (++dc->sc_cur <= dc->sc_last) { 419 #ifdef DEBUG 420 dmatimo[i] = 1; 421 #endif 422 /* 423 * Last chain segment, disable DMA interrupt. 424 */ 425 if (dc->sc_cur == dc->sc_last && 426 (dc->sc_flags & DMAF_NOINTR)) 427 dc->sc_cmd &= ~DMA_ENAB; 428 DMA_CLEAR(dc); 429 DMA_ARM(dc); 430 } else 431 dmastop(i); 432 } 433 return(found); 434 } 435 436 #ifdef DEBUG 437 void 438 dmatimeout() 439 { 440 register int i, s; 441 442 for (i = 0; i < NDMA; i++) { 443 s = splbio(); 444 if (dmatimo[i]) { 445 if (dmatimo[i] > 1) 446 printf("dma%d: timeout #%d\n", 447 i, dmatimo[i]-1); 448 dmatimo[i]++; 449 } 450 splx(s); 451 } 452 timeout(dmatimeout, (caddr_t)0, 30 * hz); 453 } 454 #endif 455