1 /* $NetBSD: bus_dma.c,v 1.49 2006/04/10 03:07:40 simonb Exp $ */ 2 3 /*- 4 * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 #define _ARM32_BUS_DMA_PRIVATE 41 42 #include <sys/cdefs.h> 43 __KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.49 2006/04/10 03:07:40 simonb Exp $"); 44 45 #include <sys/param.h> 46 #include <sys/systm.h> 47 #include <sys/kernel.h> 48 #include <sys/proc.h> 49 #include <sys/buf.h> 50 #include <sys/reboot.h> 51 #include <sys/conf.h> 52 #include <sys/file.h> 53 #include <sys/malloc.h> 54 #include <sys/mbuf.h> 55 #include <sys/vnode.h> 56 #include <sys/device.h> 57 58 #include <uvm/uvm_extern.h> 59 60 #include <machine/bus.h> 61 #include <machine/cpu.h> 62 63 #include <arm/cpufunc.h> 64 65 int _bus_dmamap_load_buffer(bus_dma_tag_t, bus_dmamap_t, void *, 66 bus_size_t, struct vmspace *, int); 67 struct arm32_dma_range *_bus_dma_inrange(struct arm32_dma_range *, 68 int, bus_addr_t); 69 70 /* 71 * Check to see if the specified page is in an allowed DMA range. 72 */ 73 inline struct arm32_dma_range * 74 _bus_dma_inrange(struct arm32_dma_range *ranges, int nranges, 75 bus_addr_t curaddr) 76 { 77 struct arm32_dma_range *dr; 78 int i; 79 80 for (i = 0, dr = ranges; i < nranges; i++, dr++) { 81 if (curaddr >= dr->dr_sysbase && 82 round_page(curaddr) <= (dr->dr_sysbase + dr->dr_len)) 83 return (dr); 84 } 85 86 return (NULL); 87 } 88 89 /* 90 * Common function to load the specified physical address into the 91 * DMA map, coalescing segments and boundary checking as necessary. 92 */ 93 static int 94 _bus_dmamap_load_paddr(bus_dma_tag_t t, bus_dmamap_t map, 95 bus_addr_t paddr, bus_size_t size) 96 { 97 bus_dma_segment_t * const segs = map->dm_segs; 98 int nseg = map->dm_nsegs; 99 bus_addr_t lastaddr = 0xdead; /* XXX gcc */ 100 bus_addr_t bmask = ~(map->_dm_boundary - 1); 101 bus_addr_t curaddr; 102 bus_size_t sgsize; 103 104 if (nseg > 0) 105 lastaddr = segs[nseg-1].ds_addr + segs[nseg-1].ds_len; 106 again: 107 sgsize = size; 108 109 /* Make sure we're in an allowed DMA range. */ 110 if (t->_ranges != NULL) { 111 /* XXX cache last result? */ 112 const struct arm32_dma_range * const dr = 113 _bus_dma_inrange(t->_ranges, t->_nranges, paddr); 114 if (dr == NULL) 115 return (EINVAL); 116 117 /* 118 * In a valid DMA range. Translate the physical 119 * memory address to an address in the DMA window. 120 */ 121 curaddr = (paddr - dr->dr_sysbase) + dr->dr_busbase; 122 } else 123 curaddr = paddr; 124 125 /* 126 * Make sure we don't cross any boundaries. 127 */ 128 if (map->_dm_boundary > 0) { 129 bus_addr_t baddr; /* next boundary address */ 130 131 baddr = (curaddr + map->_dm_boundary) & bmask; 132 if (sgsize > (baddr - curaddr)) 133 sgsize = (baddr - curaddr); 134 } 135 136 /* 137 * Insert chunk into a segment, coalescing with the 138 * previous segment if possible. 139 */ 140 if (nseg > 0 && curaddr == lastaddr && 141 segs[nseg-1].ds_len + sgsize <= map->dm_maxsegsz && 142 (map->_dm_boundary == 0 || 143 (segs[nseg-1].ds_addr & bmask) == (curaddr & bmask))) { 144 /* coalesce */ 145 segs[nseg-1].ds_len += sgsize; 146 } else if (nseg >= map->_dm_segcnt) { 147 return (EFBIG); 148 } else { 149 /* new segment */ 150 segs[nseg].ds_addr = curaddr; 151 segs[nseg].ds_len = sgsize; 152 nseg++; 153 } 154 155 lastaddr = curaddr + sgsize; 156 157 paddr += sgsize; 158 size -= sgsize; 159 if (size > 0) 160 goto again; 161 162 map->dm_nsegs = nseg; 163 return (0); 164 } 165 166 /* 167 * Common function for DMA map creation. May be called by bus-specific 168 * DMA map creation functions. 169 */ 170 int 171 _bus_dmamap_create(bus_dma_tag_t t, bus_size_t size, int nsegments, 172 bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp) 173 { 174 struct arm32_bus_dmamap *map; 175 void *mapstore; 176 size_t mapsize; 177 178 #ifdef DEBUG_DMA 179 printf("dmamap_create: t=%p size=%lx nseg=%x msegsz=%lx boundary=%lx flags=%x\n", 180 t, size, nsegments, maxsegsz, boundary, flags); 181 #endif /* DEBUG_DMA */ 182 183 /* 184 * Allocate and initialize the DMA map. The end of the map 185 * is a variable-sized array of segments, so we allocate enough 186 * room for them in one shot. 187 * 188 * Note we don't preserve the WAITOK or NOWAIT flags. Preservation 189 * of ALLOCNOW notifies others that we've reserved these resources, 190 * and they are not to be freed. 191 * 192 * The bus_dmamap_t includes one bus_dma_segment_t, hence 193 * the (nsegments - 1). 194 */ 195 mapsize = sizeof(struct arm32_bus_dmamap) + 196 (sizeof(bus_dma_segment_t) * (nsegments - 1)); 197 if ((mapstore = malloc(mapsize, M_DMAMAP, 198 (flags & BUS_DMA_NOWAIT) ? M_NOWAIT : M_WAITOK)) == NULL) 199 return (ENOMEM); 200 201 memset(mapstore, 0, mapsize); 202 map = (struct arm32_bus_dmamap *)mapstore; 203 map->_dm_size = size; 204 map->_dm_segcnt = nsegments; 205 map->_dm_maxmaxsegsz = maxsegsz; 206 map->_dm_boundary = boundary; 207 map->_dm_flags = flags & ~(BUS_DMA_WAITOK|BUS_DMA_NOWAIT); 208 map->_dm_origbuf = NULL; 209 map->_dm_buftype = ARM32_BUFTYPE_INVALID; 210 map->_dm_vmspace = vmspace_kernel(); 211 map->dm_maxsegsz = maxsegsz; 212 map->dm_mapsize = 0; /* no valid mappings */ 213 map->dm_nsegs = 0; 214 215 *dmamp = map; 216 #ifdef DEBUG_DMA 217 printf("dmamap_create:map=%p\n", map); 218 #endif /* DEBUG_DMA */ 219 return (0); 220 } 221 222 /* 223 * Common function for DMA map destruction. May be called by bus-specific 224 * DMA map destruction functions. 225 */ 226 void 227 _bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t map) 228 { 229 230 #ifdef DEBUG_DMA 231 printf("dmamap_destroy: t=%p map=%p\n", t, map); 232 #endif /* DEBUG_DMA */ 233 234 /* 235 * Explicit unload. 236 */ 237 map->dm_maxsegsz = map->_dm_maxmaxsegsz; 238 map->dm_mapsize = 0; 239 map->dm_nsegs = 0; 240 map->_dm_origbuf = NULL; 241 map->_dm_buftype = ARM32_BUFTYPE_INVALID; 242 map->_dm_vmspace = NULL; 243 244 free(map, M_DMAMAP); 245 } 246 247 /* 248 * Common function for loading a DMA map with a linear buffer. May 249 * be called by bus-specific DMA map load functions. 250 */ 251 int 252 _bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t map, void *buf, 253 bus_size_t buflen, struct proc *p, int flags) 254 { 255 int error; 256 struct vmspace *vm; 257 258 #ifdef DEBUG_DMA 259 printf("dmamap_load: t=%p map=%p buf=%p len=%lx p=%p f=%d\n", 260 t, map, buf, buflen, p, flags); 261 #endif /* DEBUG_DMA */ 262 263 /* 264 * Make sure that on error condition we return "no valid mappings". 265 */ 266 map->dm_mapsize = 0; 267 map->dm_nsegs = 0; 268 KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz); 269 270 if (buflen > map->_dm_size) 271 return (EINVAL); 272 273 if (p != NULL) { 274 vm = p->p_vmspace; 275 } else { 276 vm = vmspace_kernel(); 277 } 278 279 /* _bus_dmamap_load_buffer() clears this if we're not... */ 280 map->_dm_flags |= ARM32_DMAMAP_COHERENT; 281 282 error = _bus_dmamap_load_buffer(t, map, buf, buflen, vm, flags); 283 if (error == 0) { 284 map->dm_mapsize = buflen; 285 map->_dm_origbuf = buf; 286 map->_dm_buftype = ARM32_BUFTYPE_LINEAR; 287 map->_dm_vmspace = vm; 288 } 289 #ifdef DEBUG_DMA 290 printf("dmamap_load: error=%d\n", error); 291 #endif /* DEBUG_DMA */ 292 return (error); 293 } 294 295 /* 296 * Like _bus_dmamap_load(), but for mbufs. 297 */ 298 int 299 _bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t map, struct mbuf *m0, 300 int flags) 301 { 302 int error; 303 struct mbuf *m; 304 305 #ifdef DEBUG_DMA 306 printf("dmamap_load_mbuf: t=%p map=%p m0=%p f=%d\n", 307 t, map, m0, flags); 308 #endif /* DEBUG_DMA */ 309 310 /* 311 * Make sure that on error condition we return "no valid mappings." 312 */ 313 map->dm_mapsize = 0; 314 map->dm_nsegs = 0; 315 KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz); 316 317 #ifdef DIAGNOSTIC 318 if ((m0->m_flags & M_PKTHDR) == 0) 319 panic("_bus_dmamap_load_mbuf: no packet header"); 320 #endif /* DIAGNOSTIC */ 321 322 if (m0->m_pkthdr.len > map->_dm_size) 323 return (EINVAL); 324 325 /* 326 * Mbuf chains should almost never have coherent (i.e. 327 * un-cached) mappings, so clear that flag now. 328 */ 329 map->_dm_flags &= ~ARM32_DMAMAP_COHERENT; 330 331 error = 0; 332 for (m = m0; m != NULL && error == 0; m = m->m_next) { 333 int offset; 334 int remainbytes; 335 const struct vm_page * const *pgs; 336 paddr_t paddr; 337 int size; 338 339 if (m->m_len == 0) 340 continue; 341 switch (m->m_flags & (M_EXT|M_CLUSTER|M_EXT_PAGES)) { 342 case M_EXT|M_CLUSTER: 343 /* XXX KDASSERT */ 344 KASSERT(m->m_ext.ext_paddr != M_PADDR_INVALID); 345 paddr = m->m_ext.ext_paddr + 346 (m->m_data - m->m_ext.ext_buf); 347 size = m->m_len; 348 error = _bus_dmamap_load_paddr(t, map, paddr, size); 349 break; 350 351 case M_EXT|M_EXT_PAGES: 352 KASSERT(m->m_ext.ext_buf <= m->m_data); 353 KASSERT(m->m_data <= 354 m->m_ext.ext_buf + m->m_ext.ext_size); 355 356 offset = (vaddr_t)m->m_data - 357 trunc_page((vaddr_t)m->m_ext.ext_buf); 358 remainbytes = m->m_len; 359 360 /* skip uninteresting pages */ 361 pgs = (const struct vm_page * const *) 362 m->m_ext.ext_pgs + (offset >> PAGE_SHIFT); 363 364 offset &= PAGE_MASK; /* offset in the first page */ 365 366 /* load each page */ 367 while (remainbytes > 0) { 368 const struct vm_page *pg; 369 370 size = MIN(remainbytes, PAGE_SIZE - offset); 371 372 pg = *pgs++; 373 KASSERT(pg); 374 paddr = VM_PAGE_TO_PHYS(pg) + offset; 375 376 error = _bus_dmamap_load_paddr(t, map, 377 paddr, size); 378 if (error) 379 break; 380 offset = 0; 381 remainbytes -= size; 382 } 383 break; 384 385 case 0: 386 paddr = m->m_paddr + M_BUFOFFSET(m) + 387 (m->m_data - M_BUFADDR(m)); 388 size = m->m_len; 389 error = _bus_dmamap_load_paddr(t, map, paddr, size); 390 break; 391 392 default: 393 error = _bus_dmamap_load_buffer(t, map, m->m_data, 394 m->m_len, vmspace_kernel(), flags); 395 } 396 } 397 if (error == 0) { 398 map->dm_mapsize = m0->m_pkthdr.len; 399 map->_dm_origbuf = m0; 400 map->_dm_buftype = ARM32_BUFTYPE_MBUF; 401 map->_dm_vmspace = vmspace_kernel(); /* always kernel */ 402 } 403 #ifdef DEBUG_DMA 404 printf("dmamap_load_mbuf: error=%d\n", error); 405 #endif /* DEBUG_DMA */ 406 return (error); 407 } 408 409 /* 410 * Like _bus_dmamap_load(), but for uios. 411 */ 412 int 413 _bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t map, struct uio *uio, 414 int flags) 415 { 416 int i, error; 417 bus_size_t minlen, resid; 418 struct iovec *iov; 419 caddr_t addr; 420 421 /* 422 * Make sure that on error condition we return "no valid mappings." 423 */ 424 map->dm_mapsize = 0; 425 map->dm_nsegs = 0; 426 KASSERT(map->dm_maxsegsz <= map->_dm_maxmaxsegsz); 427 428 resid = uio->uio_resid; 429 iov = uio->uio_iov; 430 431 /* _bus_dmamap_load_buffer() clears this if we're not... */ 432 map->_dm_flags |= ARM32_DMAMAP_COHERENT; 433 434 error = 0; 435 for (i = 0; i < uio->uio_iovcnt && resid != 0 && error == 0; i++) { 436 /* 437 * Now at the first iovec to load. Load each iovec 438 * until we have exhausted the residual count. 439 */ 440 minlen = resid < iov[i].iov_len ? resid : iov[i].iov_len; 441 addr = (caddr_t)iov[i].iov_base; 442 443 error = _bus_dmamap_load_buffer(t, map, addr, minlen, 444 uio->uio_vmspace, flags); 445 446 resid -= minlen; 447 } 448 if (error == 0) { 449 map->dm_mapsize = uio->uio_resid; 450 map->_dm_origbuf = uio; 451 map->_dm_buftype = ARM32_BUFTYPE_UIO; 452 map->_dm_vmspace = uio->uio_vmspace; 453 } 454 return (error); 455 } 456 457 /* 458 * Like _bus_dmamap_load(), but for raw memory allocated with 459 * bus_dmamem_alloc(). 460 */ 461 int 462 _bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t map, 463 bus_dma_segment_t *segs, int nsegs, bus_size_t size, int flags) 464 { 465 466 panic("_bus_dmamap_load_raw: not implemented"); 467 } 468 469 /* 470 * Common function for unloading a DMA map. May be called by 471 * bus-specific DMA map unload functions. 472 */ 473 void 474 _bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t map) 475 { 476 477 #ifdef DEBUG_DMA 478 printf("dmamap_unload: t=%p map=%p\n", t, map); 479 #endif /* DEBUG_DMA */ 480 481 /* 482 * No resources to free; just mark the mappings as 483 * invalid. 484 */ 485 map->dm_mapsize = 0; 486 map->dm_nsegs = 0; 487 map->_dm_origbuf = NULL; 488 map->_dm_buftype = ARM32_BUFTYPE_INVALID; 489 map->_dm_vmspace = NULL; 490 } 491 492 static inline void 493 _bus_dmamap_sync_linear(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, 494 bus_size_t len, int ops) 495 { 496 vaddr_t addr = (vaddr_t) map->_dm_origbuf; 497 498 addr += offset; 499 500 switch (ops) { 501 case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE: 502 cpu_dcache_wbinv_range(addr, len); 503 break; 504 505 case BUS_DMASYNC_PREREAD: 506 if (((addr | len) & arm_dcache_align_mask) == 0) 507 cpu_dcache_inv_range(addr, len); 508 else 509 cpu_dcache_wbinv_range(addr, len); 510 break; 511 512 case BUS_DMASYNC_PREWRITE: 513 cpu_dcache_wb_range(addr, len); 514 break; 515 } 516 } 517 518 static inline void 519 _bus_dmamap_sync_mbuf(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, 520 bus_size_t len, int ops) 521 { 522 struct mbuf *m, *m0 = map->_dm_origbuf; 523 bus_size_t minlen, moff; 524 vaddr_t maddr; 525 526 for (moff = offset, m = m0; m != NULL && len != 0; m = m->m_next) { 527 /* Find the beginning mbuf. */ 528 if (moff >= m->m_len) { 529 moff -= m->m_len; 530 continue; 531 } 532 533 /* 534 * Now at the first mbuf to sync; nail each one until 535 * we have exhausted the length. 536 */ 537 minlen = m->m_len - moff; 538 if (len < minlen) 539 minlen = len; 540 541 maddr = mtod(m, vaddr_t); 542 maddr += moff; 543 544 /* 545 * We can save a lot of work here if we know the mapping 546 * is read-only at the MMU: 547 * 548 * If a mapping is read-only, no dirty cache blocks will 549 * exist for it. If a writable mapping was made read-only, 550 * we know any dirty cache lines for the range will have 551 * been cleaned for us already. Therefore, if the upper 552 * layer can tell us we have a read-only mapping, we can 553 * skip all cache cleaning. 554 * 555 * NOTE: This only works if we know the pmap cleans pages 556 * before making a read-write -> read-only transition. If 557 * this ever becomes non-true (e.g. Physically Indexed 558 * cache), this will have to be revisited. 559 */ 560 switch (ops) { 561 case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE: 562 if (! M_ROMAP(m)) { 563 cpu_dcache_wbinv_range(maddr, minlen); 564 break; 565 } 566 /* else FALLTHROUGH */ 567 568 case BUS_DMASYNC_PREREAD: 569 if (((maddr | minlen) & arm_dcache_align_mask) == 0) 570 cpu_dcache_inv_range(maddr, minlen); 571 else 572 cpu_dcache_wbinv_range(maddr, minlen); 573 break; 574 575 case BUS_DMASYNC_PREWRITE: 576 if (! M_ROMAP(m)) 577 cpu_dcache_wb_range(maddr, minlen); 578 break; 579 } 580 moff = 0; 581 len -= minlen; 582 } 583 } 584 585 static inline void 586 _bus_dmamap_sync_uio(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, 587 bus_size_t len, int ops) 588 { 589 struct uio *uio = map->_dm_origbuf; 590 struct iovec *iov; 591 bus_size_t minlen, ioff; 592 vaddr_t addr; 593 594 for (iov = uio->uio_iov, ioff = offset; len != 0; iov++) { 595 /* Find the beginning iovec. */ 596 if (ioff >= iov->iov_len) { 597 ioff -= iov->iov_len; 598 continue; 599 } 600 601 /* 602 * Now at the first iovec to sync; nail each one until 603 * we have exhausted the length. 604 */ 605 minlen = iov->iov_len - ioff; 606 if (len < minlen) 607 minlen = len; 608 609 addr = (vaddr_t) iov->iov_base; 610 addr += ioff; 611 612 switch (ops) { 613 case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE: 614 cpu_dcache_wbinv_range(addr, minlen); 615 break; 616 617 case BUS_DMASYNC_PREREAD: 618 if (((addr | minlen) & arm_dcache_align_mask) == 0) 619 cpu_dcache_inv_range(addr, minlen); 620 else 621 cpu_dcache_wbinv_range(addr, minlen); 622 break; 623 624 case BUS_DMASYNC_PREWRITE: 625 cpu_dcache_wb_range(addr, minlen); 626 break; 627 } 628 ioff = 0; 629 len -= minlen; 630 } 631 } 632 633 /* 634 * Common function for DMA map synchronization. May be called 635 * by bus-specific DMA map synchronization functions. 636 * 637 * This version works for the Virtually Indexed Virtually Tagged 638 * cache found on 32-bit ARM processors. 639 * 640 * XXX Should have separate versions for write-through vs. 641 * XXX write-back caches. We currently assume write-back 642 * XXX here, which is not as efficient as it could be for 643 * XXX the write-through case. 644 */ 645 void 646 _bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t map, bus_addr_t offset, 647 bus_size_t len, int ops) 648 { 649 650 #ifdef DEBUG_DMA 651 printf("dmamap_sync: t=%p map=%p offset=%lx len=%lx ops=%x\n", 652 t, map, offset, len, ops); 653 #endif /* DEBUG_DMA */ 654 655 /* 656 * Mixing of PRE and POST operations is not allowed. 657 */ 658 if ((ops & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) != 0 && 659 (ops & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)) != 0) 660 panic("_bus_dmamap_sync: mix PRE and POST"); 661 662 #ifdef DIAGNOSTIC 663 if (offset >= map->dm_mapsize) 664 panic("_bus_dmamap_sync: bad offset %lu (map size is %lu)", 665 offset, map->dm_mapsize); 666 if (len == 0 || (offset + len) > map->dm_mapsize) 667 panic("_bus_dmamap_sync: bad length"); 668 #endif 669 670 /* 671 * For a virtually-indexed write-back cache, we need 672 * to do the following things: 673 * 674 * PREREAD -- Invalidate the D-cache. We do this 675 * here in case a write-back is required by the back-end. 676 * 677 * PREWRITE -- Write-back the D-cache. Note that if 678 * we are doing a PREREAD|PREWRITE, we can collapse 679 * the whole thing into a single Wb-Inv. 680 * 681 * POSTREAD -- Nothing. 682 * 683 * POSTWRITE -- Nothing. 684 */ 685 686 ops &= (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 687 if (ops == 0) 688 return; 689 690 /* Skip cache frobbing if mapping was COHERENT. */ 691 if (map->_dm_flags & ARM32_DMAMAP_COHERENT) { 692 /* Drain the write buffer. */ 693 cpu_drain_writebuf(); 694 return; 695 } 696 697 /* 698 * If the mapping belongs to a non-kernel vmspace, and the 699 * vmspace has not been active since the last time a full 700 * cache flush was performed, we don't need to do anything. 701 */ 702 if (__predict_false(!VMSPACE_IS_KERNEL_P(map->_dm_vmspace) && 703 vm_map_pmap(&map->_dm_vmspace->vm_map)->pm_cstate.cs_cache_d == 0)) 704 return; 705 706 switch (map->_dm_buftype) { 707 case ARM32_BUFTYPE_LINEAR: 708 _bus_dmamap_sync_linear(t, map, offset, len, ops); 709 break; 710 711 case ARM32_BUFTYPE_MBUF: 712 _bus_dmamap_sync_mbuf(t, map, offset, len, ops); 713 break; 714 715 case ARM32_BUFTYPE_UIO: 716 _bus_dmamap_sync_uio(t, map, offset, len, ops); 717 break; 718 719 case ARM32_BUFTYPE_RAW: 720 panic("_bus_dmamap_sync: ARM32_BUFTYPE_RAW"); 721 break; 722 723 case ARM32_BUFTYPE_INVALID: 724 panic("_bus_dmamap_sync: ARM32_BUFTYPE_INVALID"); 725 break; 726 727 default: 728 printf("unknown buffer type %d\n", map->_dm_buftype); 729 panic("_bus_dmamap_sync"); 730 } 731 732 /* Drain the write buffer. */ 733 cpu_drain_writebuf(); 734 } 735 736 /* 737 * Common function for DMA-safe memory allocation. May be called 738 * by bus-specific DMA memory allocation functions. 739 */ 740 741 extern paddr_t physical_start; 742 extern paddr_t physical_end; 743 744 int 745 _bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment, 746 bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, 747 int flags) 748 { 749 struct arm32_dma_range *dr; 750 int error, i; 751 752 #ifdef DEBUG_DMA 753 printf("dmamem_alloc t=%p size=%lx align=%lx boundary=%lx " 754 "segs=%p nsegs=%x rsegs=%p flags=%x\n", t, size, alignment, 755 boundary, segs, nsegs, rsegs, flags); 756 #endif 757 758 if ((dr = t->_ranges) != NULL) { 759 error = ENOMEM; 760 for (i = 0; i < t->_nranges; i++, dr++) { 761 if (dr->dr_len == 0) 762 continue; 763 error = _bus_dmamem_alloc_range(t, size, alignment, 764 boundary, segs, nsegs, rsegs, flags, 765 trunc_page(dr->dr_sysbase), 766 trunc_page(dr->dr_sysbase + dr->dr_len)); 767 if (error == 0) 768 break; 769 } 770 } else { 771 error = _bus_dmamem_alloc_range(t, size, alignment, boundary, 772 segs, nsegs, rsegs, flags, trunc_page(physical_start), 773 trunc_page(physical_end)); 774 } 775 776 #ifdef DEBUG_DMA 777 printf("dmamem_alloc: =%d\n", error); 778 #endif 779 780 return(error); 781 } 782 783 /* 784 * Common function for freeing DMA-safe memory. May be called by 785 * bus-specific DMA memory free functions. 786 */ 787 void 788 _bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs) 789 { 790 struct vm_page *m; 791 bus_addr_t addr; 792 struct pglist mlist; 793 int curseg; 794 795 #ifdef DEBUG_DMA 796 printf("dmamem_free: t=%p segs=%p nsegs=%x\n", t, segs, nsegs); 797 #endif /* DEBUG_DMA */ 798 799 /* 800 * Build a list of pages to free back to the VM system. 801 */ 802 TAILQ_INIT(&mlist); 803 for (curseg = 0; curseg < nsegs; curseg++) { 804 for (addr = segs[curseg].ds_addr; 805 addr < (segs[curseg].ds_addr + segs[curseg].ds_len); 806 addr += PAGE_SIZE) { 807 m = PHYS_TO_VM_PAGE(addr); 808 TAILQ_INSERT_TAIL(&mlist, m, pageq); 809 } 810 } 811 uvm_pglistfree(&mlist); 812 } 813 814 /* 815 * Common function for mapping DMA-safe memory. May be called by 816 * bus-specific DMA memory map functions. 817 */ 818 int 819 _bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, 820 size_t size, caddr_t *kvap, int flags) 821 { 822 vaddr_t va; 823 bus_addr_t addr; 824 int curseg; 825 pt_entry_t *ptep/*, pte*/; 826 const uvm_flag_t kmflags = 827 (flags & BUS_DMA_NOWAIT) != 0 ? UVM_KMF_NOWAIT : 0; 828 829 #ifdef DEBUG_DMA 830 printf("dmamem_map: t=%p segs=%p nsegs=%x size=%lx flags=%x\n", t, 831 segs, nsegs, (unsigned long)size, flags); 832 #endif /* DEBUG_DMA */ 833 834 size = round_page(size); 835 va = uvm_km_alloc(kernel_map, size, 0, UVM_KMF_VAONLY | kmflags); 836 837 if (va == 0) 838 return (ENOMEM); 839 840 *kvap = (caddr_t)va; 841 842 for (curseg = 0; curseg < nsegs; curseg++) { 843 for (addr = segs[curseg].ds_addr; 844 addr < (segs[curseg].ds_addr + segs[curseg].ds_len); 845 addr += PAGE_SIZE, va += PAGE_SIZE, size -= PAGE_SIZE) { 846 #ifdef DEBUG_DMA 847 printf("wiring p%lx to v%lx", addr, va); 848 #endif /* DEBUG_DMA */ 849 if (size == 0) 850 panic("_bus_dmamem_map: size botch"); 851 pmap_enter(pmap_kernel(), va, addr, 852 VM_PROT_READ | VM_PROT_WRITE, 853 VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED); 854 /* 855 * If the memory must remain coherent with the 856 * cache then we must make the memory uncacheable 857 * in order to maintain virtual cache coherency. 858 * We must also guarantee the cache does not already 859 * contain the virtal addresses we are making 860 * uncacheable. 861 */ 862 if (flags & BUS_DMA_COHERENT) { 863 cpu_dcache_wbinv_range(va, PAGE_SIZE); 864 cpu_drain_writebuf(); 865 ptep = vtopte(va); 866 *ptep &= ~L2_S_CACHE_MASK; 867 PTE_SYNC(ptep); 868 tlb_flush(); 869 } 870 #ifdef DEBUG_DMA 871 ptep = vtopte(va); 872 printf(" pte=v%p *pte=%x\n", ptep, *ptep); 873 #endif /* DEBUG_DMA */ 874 } 875 } 876 pmap_update(pmap_kernel()); 877 #ifdef DEBUG_DMA 878 printf("dmamem_map: =%p\n", *kvap); 879 #endif /* DEBUG_DMA */ 880 return (0); 881 } 882 883 /* 884 * Common function for unmapping DMA-safe memory. May be called by 885 * bus-specific DMA memory unmapping functions. 886 */ 887 void 888 _bus_dmamem_unmap(bus_dma_tag_t t, caddr_t kva, size_t size) 889 { 890 891 #ifdef DEBUG_DMA 892 printf("dmamem_unmap: t=%p kva=%p size=%lx\n", t, kva, 893 (unsigned long)size); 894 #endif /* DEBUG_DMA */ 895 #ifdef DIAGNOSTIC 896 if ((u_long)kva & PGOFSET) 897 panic("_bus_dmamem_unmap"); 898 #endif /* DIAGNOSTIC */ 899 900 size = round_page(size); 901 pmap_remove(pmap_kernel(), (vaddr_t)kva, (vaddr_t)kva + size); 902 pmap_update(pmap_kernel()); 903 uvm_km_free(kernel_map, (vaddr_t)kva, size, UVM_KMF_VAONLY); 904 } 905 906 /* 907 * Common functin for mmap(2)'ing DMA-safe memory. May be called by 908 * bus-specific DMA mmap(2)'ing functions. 909 */ 910 paddr_t 911 _bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *segs, int nsegs, 912 off_t off, int prot, int flags) 913 { 914 int i; 915 916 for (i = 0; i < nsegs; i++) { 917 #ifdef DIAGNOSTIC 918 if (off & PGOFSET) 919 panic("_bus_dmamem_mmap: offset unaligned"); 920 if (segs[i].ds_addr & PGOFSET) 921 panic("_bus_dmamem_mmap: segment unaligned"); 922 if (segs[i].ds_len & PGOFSET) 923 panic("_bus_dmamem_mmap: segment size not multiple" 924 " of page size"); 925 #endif /* DIAGNOSTIC */ 926 if (off >= segs[i].ds_len) { 927 off -= segs[i].ds_len; 928 continue; 929 } 930 931 return (arm_btop((u_long)segs[i].ds_addr + off)); 932 } 933 934 /* Page not found. */ 935 return (-1); 936 } 937 938 /********************************************************************** 939 * DMA utility functions 940 **********************************************************************/ 941 942 /* 943 * Utility function to load a linear buffer. lastaddrp holds state 944 * between invocations (for multiple-buffer loads). segp contains 945 * the starting segment on entrace, and the ending segment on exit. 946 * first indicates if this is the first invocation of this function. 947 */ 948 int 949 _bus_dmamap_load_buffer(bus_dma_tag_t t, bus_dmamap_t map, void *buf, 950 bus_size_t buflen, struct vmspace *vm, int flags) 951 { 952 bus_size_t sgsize; 953 bus_addr_t curaddr; 954 vaddr_t vaddr = (vaddr_t)buf; 955 pd_entry_t *pde; 956 pt_entry_t pte; 957 int error; 958 pmap_t pmap; 959 pt_entry_t *ptep; 960 961 #ifdef DEBUG_DMA 962 printf("_bus_dmamem_load_buffer(buf=%p, len=%lx, flags=%d)\n", 963 buf, buflen, flags); 964 #endif /* DEBUG_DMA */ 965 966 pmap = vm_map_pmap(&vm->vm_map); 967 968 while (buflen > 0) { 969 /* 970 * Get the physical address for this segment. 971 * 972 * XXX Don't support checking for coherent mappings 973 * XXX in user address space. 974 */ 975 if (__predict_true(pmap == pmap_kernel())) { 976 (void) pmap_get_pde_pte(pmap, vaddr, &pde, &ptep); 977 if (__predict_false(pmap_pde_section(pde))) { 978 curaddr = (*pde & L1_S_FRAME) | 979 (vaddr & L1_S_OFFSET); 980 if (*pde & L1_S_CACHE_MASK) { 981 map->_dm_flags &= 982 ~ARM32_DMAMAP_COHERENT; 983 } 984 } else { 985 pte = *ptep; 986 KDASSERT((pte & L2_TYPE_MASK) != L2_TYPE_INV); 987 if (__predict_false((pte & L2_TYPE_MASK) 988 == L2_TYPE_L)) { 989 curaddr = (pte & L2_L_FRAME) | 990 (vaddr & L2_L_OFFSET); 991 if (pte & L2_L_CACHE_MASK) { 992 map->_dm_flags &= 993 ~ARM32_DMAMAP_COHERENT; 994 } 995 } else { 996 curaddr = (pte & L2_S_FRAME) | 997 (vaddr & L2_S_OFFSET); 998 if (pte & L2_S_CACHE_MASK) { 999 map->_dm_flags &= 1000 ~ARM32_DMAMAP_COHERENT; 1001 } 1002 } 1003 } 1004 } else { 1005 (void) pmap_extract(pmap, vaddr, &curaddr); 1006 map->_dm_flags &= ~ARM32_DMAMAP_COHERENT; 1007 } 1008 1009 /* 1010 * Compute the segment size, and adjust counts. 1011 */ 1012 sgsize = PAGE_SIZE - ((u_long)vaddr & PGOFSET); 1013 if (buflen < sgsize) 1014 sgsize = buflen; 1015 1016 error = _bus_dmamap_load_paddr(t, map, curaddr, sgsize); 1017 if (error) 1018 return (error); 1019 1020 vaddr += sgsize; 1021 buflen -= sgsize; 1022 } 1023 1024 return (0); 1025 } 1026 1027 /* 1028 * Allocate physical memory from the given physical address range. 1029 * Called by DMA-safe memory allocation methods. 1030 */ 1031 int 1032 _bus_dmamem_alloc_range(bus_dma_tag_t t, bus_size_t size, bus_size_t alignment, 1033 bus_size_t boundary, bus_dma_segment_t *segs, int nsegs, int *rsegs, 1034 int flags, paddr_t low, paddr_t high) 1035 { 1036 paddr_t curaddr, lastaddr; 1037 struct vm_page *m; 1038 struct pglist mlist; 1039 int curseg, error; 1040 1041 #ifdef DEBUG_DMA 1042 printf("alloc_range: t=%p size=%lx align=%lx boundary=%lx segs=%p nsegs=%x rsegs=%p flags=%x lo=%lx hi=%lx\n", 1043 t, size, alignment, boundary, segs, nsegs, rsegs, flags, low, high); 1044 #endif /* DEBUG_DMA */ 1045 1046 /* Always round the size. */ 1047 size = round_page(size); 1048 1049 /* 1050 * Allocate pages from the VM system. 1051 */ 1052 error = uvm_pglistalloc(size, low, high, alignment, boundary, 1053 &mlist, nsegs, (flags & BUS_DMA_NOWAIT) == 0); 1054 if (error) 1055 return (error); 1056 1057 /* 1058 * Compute the location, size, and number of segments actually 1059 * returned by the VM code. 1060 */ 1061 m = TAILQ_FIRST(&mlist); 1062 curseg = 0; 1063 lastaddr = segs[curseg].ds_addr = VM_PAGE_TO_PHYS(m); 1064 segs[curseg].ds_len = PAGE_SIZE; 1065 #ifdef DEBUG_DMA 1066 printf("alloc: page %lx\n", lastaddr); 1067 #endif /* DEBUG_DMA */ 1068 m = TAILQ_NEXT(m, pageq); 1069 1070 for (; m != NULL; m = TAILQ_NEXT(m, pageq)) { 1071 curaddr = VM_PAGE_TO_PHYS(m); 1072 #ifdef DIAGNOSTIC 1073 if (curaddr < low || curaddr >= high) { 1074 printf("uvm_pglistalloc returned non-sensical" 1075 " address 0x%lx\n", curaddr); 1076 panic("_bus_dmamem_alloc_range"); 1077 } 1078 #endif /* DIAGNOSTIC */ 1079 #ifdef DEBUG_DMA 1080 printf("alloc: page %lx\n", curaddr); 1081 #endif /* DEBUG_DMA */ 1082 if (curaddr == (lastaddr + PAGE_SIZE)) 1083 segs[curseg].ds_len += PAGE_SIZE; 1084 else { 1085 curseg++; 1086 segs[curseg].ds_addr = curaddr; 1087 segs[curseg].ds_len = PAGE_SIZE; 1088 } 1089 lastaddr = curaddr; 1090 } 1091 1092 *rsegs = curseg + 1; 1093 1094 return (0); 1095 } 1096 1097 /* 1098 * Check if a memory region intersects with a DMA range, and return the 1099 * page-rounded intersection if it does. 1100 */ 1101 int 1102 arm32_dma_range_intersect(struct arm32_dma_range *ranges, int nranges, 1103 paddr_t pa, psize_t size, paddr_t *pap, psize_t *sizep) 1104 { 1105 struct arm32_dma_range *dr; 1106 int i; 1107 1108 if (ranges == NULL) 1109 return (0); 1110 1111 for (i = 0, dr = ranges; i < nranges; i++, dr++) { 1112 if (dr->dr_sysbase <= pa && 1113 pa < (dr->dr_sysbase + dr->dr_len)) { 1114 /* 1115 * Beginning of region intersects with this range. 1116 */ 1117 *pap = trunc_page(pa); 1118 *sizep = round_page(min(pa + size, 1119 dr->dr_sysbase + dr->dr_len) - pa); 1120 return (1); 1121 } 1122 if (pa < dr->dr_sysbase && dr->dr_sysbase < (pa + size)) { 1123 /* 1124 * End of region intersects with this range. 1125 */ 1126 *pap = trunc_page(dr->dr_sysbase); 1127 *sizep = round_page(min((pa + size) - dr->dr_sysbase, 1128 dr->dr_len)); 1129 return (1); 1130 } 1131 } 1132 1133 /* No intersection found. */ 1134 return (0); 1135 } 1136