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