busdma_machdep-v6.c (274538) | busdma_machdep-v6.c (274545) |
---|---|
1/*- | 1/*- |
2 * Copyright (c) 2012 Ian Lepore | 2 * Copyright (c) 2012-2014 Ian Lepore |
3 * Copyright (c) 2010 Mark Tinguely 4 * Copyright (c) 2004 Olivier Houchard 5 * Copyright (c) 2002 Peter Grehan 6 * Copyright (c) 1997, 1998 Justin T. Gibbs. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions --- 15 unchanged lines hidden (view full) --- 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * From i386/busdma_machdep.c 191438 2009-04-23 20:24:19Z jhb 31 */ 32 33#include <sys/cdefs.h> | 3 * Copyright (c) 2010 Mark Tinguely 4 * Copyright (c) 2004 Olivier Houchard 5 * Copyright (c) 2002 Peter Grehan 6 * Copyright (c) 1997, 1998 Justin T. Gibbs. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions --- 15 unchanged lines hidden (view full) --- 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * From i386/busdma_machdep.c 191438 2009-04-23 20:24:19Z jhb 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/arm/arm/busdma_machdep-v6.c 274538 2014-11-15 03:39:58Z ian $"); | 34__FBSDID("$FreeBSD: head/sys/arm/arm/busdma_machdep-v6.c 274545 2014-11-15 05:40:20Z ian $"); |
35 36#define _ARM32_BUS_DMA_PRIVATE 37#include <sys/param.h> 38#include <sys/kdb.h> 39#include <ddb/ddb.h> 40#include <ddb/db_output.h> 41#include <sys/systm.h> 42#include <sys/malloc.h> --- 298 unchanged lines hidden (view full) --- 341 * Note that the addr argument might be either virtual or physical. It doesn't 342 * matter because we only look at the low-order bits, which are the same in both 343 * address spaces. 344 */ 345static __inline int 346might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr, 347 bus_size_t size) 348{ | 35 36#define _ARM32_BUS_DMA_PRIVATE 37#include <sys/param.h> 38#include <sys/kdb.h> 39#include <ddb/ddb.h> 40#include <ddb/db_output.h> 41#include <sys/systm.h> 42#include <sys/malloc.h> --- 298 unchanged lines hidden (view full) --- 341 * Note that the addr argument might be either virtual or physical. It doesn't 342 * matter because we only look at the low-order bits, which are the same in both 343 * address spaces. 344 */ 345static __inline int 346might_bounce(bus_dma_tag_t dmat, bus_dmamap_t map, bus_addr_t addr, 347 bus_size_t size) 348{ |
349 |
|
349 return ((dmat->flags & BUS_DMA_EXCL_BOUNCE) || 350 alignment_bounce(dmat, addr) || 351 cacheline_bounce(map, addr, size)); 352} 353 354/* 355 * Return true if we must bounce the DMA described by paddr and size. 356 * --- 82 unchanged lines hidden (view full) --- 439 * dflt_lock should never get called. It gets put into the dma tag when 440 * lockfunc == NULL, which is only valid if the maps that are associated 441 * with the tag are meant to never be defered. 442 * XXX Should have a way to identify which driver is responsible here. 443 */ 444static void 445dflt_lock(void *arg, bus_dma_lock_op_t op) 446{ | 350 return ((dmat->flags & BUS_DMA_EXCL_BOUNCE) || 351 alignment_bounce(dmat, addr) || 352 cacheline_bounce(map, addr, size)); 353} 354 355/* 356 * Return true if we must bounce the DMA described by paddr and size. 357 * --- 82 unchanged lines hidden (view full) --- 440 * dflt_lock should never get called. It gets put into the dma tag when 441 * lockfunc == NULL, which is only valid if the maps that are associated 442 * with the tag are meant to never be defered. 443 * XXX Should have a way to identify which driver is responsible here. 444 */ 445static void 446dflt_lock(void *arg, bus_dma_lock_op_t op) 447{ |
448 |
|
447 panic("driver error: busdma dflt_lock called"); 448} 449 450/* 451 * Allocate a device specific dma_tag. 452 */ 453int 454bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, --- 165 unchanged lines hidden (view full) --- 620 } 621out: 622 CTR3(KTR_BUSDMA, "%s tag %p error %d", __func__, dmat_copy, error); 623 return (error); 624} 625 626static int allocate_bz_and_pages(bus_dma_tag_t dmat, bus_dmamap_t mapp) 627{ | 449 panic("driver error: busdma dflt_lock called"); 450} 451 452/* 453 * Allocate a device specific dma_tag. 454 */ 455int 456bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, --- 165 unchanged lines hidden (view full) --- 622 } 623out: 624 CTR3(KTR_BUSDMA, "%s tag %p error %d", __func__, dmat_copy, error); 625 return (error); 626} 627 628static int allocate_bz_and_pages(bus_dma_tag_t dmat, bus_dmamap_t mapp) 629{ |
628 struct bounce_zone *bz; | 630 struct bounce_zone *bz; |
629 int maxpages; 630 int error; 631 632 if (dmat->bounce_zone == NULL) 633 if ((error = alloc_bounce_zone(dmat)) != 0) 634 return (error); 635 bz = dmat->bounce_zone; 636 /* Initialize the new map */ --- 610 unchanged lines hidden (view full) --- 1247 map->pagesreserved = 0; 1248 map->pagesneeded = 0; 1249 } 1250 map->sync_count = 0; 1251 map->flags &= ~DMAMAP_MBUF; 1252} 1253 1254#ifdef notyetbounceuser | 631 int maxpages; 632 int error; 633 634 if (dmat->bounce_zone == NULL) 635 if ((error = alloc_bounce_zone(dmat)) != 0) 636 return (error); 637 bz = dmat->bounce_zone; 638 /* Initialize the new map */ --- 610 unchanged lines hidden (view full) --- 1249 map->pagesreserved = 0; 1250 map->pagesneeded = 0; 1251 } 1252 map->sync_count = 0; 1253 map->flags &= ~DMAMAP_MBUF; 1254} 1255 1256#ifdef notyetbounceuser |
1255 /* If busdma uses user pages, then the interrupt handler could 1256 * be use the kernel vm mapping. Both bounce pages and sync list 1257 * do not cross page boundaries. 1258 * Below is a rough sequence that a person would do to fix the 1259 * user page reference in the kernel vmspace. This would be 1260 * done in the dma post routine. 1261 */ | 1257/* If busdma uses user pages, then the interrupt handler could 1258 * be use the kernel vm mapping. Both bounce pages and sync list 1259 * do not cross page boundaries. 1260 * Below is a rough sequence that a person would do to fix the 1261 * user page reference in the kernel vmspace. This would be 1262 * done in the dma post routine. 1263 */ |
1262void 1263_bus_dmamap_fix_user(vm_offset_t buf, bus_size_t len, 1264 pmap_t pmap, int op) 1265{ 1266 bus_size_t sgsize; 1267 bus_addr_t curaddr; 1268 vm_offset_t va; 1269 | 1264void 1265_bus_dmamap_fix_user(vm_offset_t buf, bus_size_t len, 1266 pmap_t pmap, int op) 1267{ 1268 bus_size_t sgsize; 1269 bus_addr_t curaddr; 1270 vm_offset_t va; 1271 |
1270 /* each synclist entry is contained within a single page. 1271 * 1272 * this would be needed if BUS_DMASYNC_POSTxxxx was implemented 1273 */ | 1272 /* 1273 * each synclist entry is contained within a single page. 1274 * this would be needed if BUS_DMASYNC_POSTxxxx was implemented 1275 */ |
1274 curaddr = pmap_extract(pmap, buf); 1275 va = pmap_dma_map(curaddr); 1276 switch (op) { 1277 case SYNC_USER_INV: 1278 cpu_dcache_wb_range(va, sgsize); 1279 break; 1280 1281 case SYNC_USER_COPYTO: --- 124 unchanged lines hidden (view full) --- 1406 sl = &map->slist[0]; 1407 end = &map->slist[map->sync_count]; 1408 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x " 1409 "performing sync", __func__, dmat, dmat->flags, op); 1410 1411 switch (op) { 1412 case BUS_DMASYNC_PREWRITE: 1413 while (sl != end) { | 1276 curaddr = pmap_extract(pmap, buf); 1277 va = pmap_dma_map(curaddr); 1278 switch (op) { 1279 case SYNC_USER_INV: 1280 cpu_dcache_wb_range(va, sgsize); 1281 break; 1282 1283 case SYNC_USER_COPYTO: --- 124 unchanged lines hidden (view full) --- 1408 sl = &map->slist[0]; 1409 end = &map->slist[map->sync_count]; 1410 CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x " 1411 "performing sync", __func__, dmat, dmat->flags, op); 1412 1413 switch (op) { 1414 case BUS_DMASYNC_PREWRITE: 1415 while (sl != end) { |
1414 cpu_dcache_wb_range(sl->vaddr, sl->datacount); 1415 l2cache_wb_range(sl->vaddr, sl->busaddr, 1416 sl->datacount); 1417 sl++; | 1416 cpu_dcache_wb_range(sl->vaddr, sl->datacount); 1417 l2cache_wb_range(sl->vaddr, sl->busaddr, 1418 sl->datacount); 1419 sl++; |
1418 } 1419 break; 1420 1421 case BUS_DMASYNC_PREREAD: 1422 while (sl != end) { 1423 cpu_dcache_inv_range(sl->vaddr, sl->datacount); 1424 l2cache_inv_range(sl->vaddr, sl->busaddr, 1425 sl->datacount); --- 31 unchanged lines hidden (view full) --- 1457 STAILQ_INIT(&bounce_map_callbacklist); 1458 mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF); 1459} 1460SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL); 1461 1462static struct sysctl_ctx_list * 1463busdma_sysctl_tree(struct bounce_zone *bz) 1464{ | 1420 } 1421 break; 1422 1423 case BUS_DMASYNC_PREREAD: 1424 while (sl != end) { 1425 cpu_dcache_inv_range(sl->vaddr, sl->datacount); 1426 l2cache_inv_range(sl->vaddr, sl->busaddr, 1427 sl->datacount); --- 31 unchanged lines hidden (view full) --- 1459 STAILQ_INIT(&bounce_map_callbacklist); 1460 mtx_init(&bounce_lock, "bounce pages lock", NULL, MTX_DEF); 1461} 1462SYSINIT(bpages, SI_SUB_LOCK, SI_ORDER_ANY, init_bounce_pages, NULL); 1463 1464static struct sysctl_ctx_list * 1465busdma_sysctl_tree(struct bounce_zone *bz) 1466{ |
1467 |
|
1465 return (&bz->sysctl_tree); 1466} 1467 1468static struct sysctl_oid * 1469busdma_sysctl_tree_top(struct bounce_zone *bz) 1470{ | 1468 return (&bz->sysctl_tree); 1469} 1470 1471static struct sysctl_oid * 1472busdma_sysctl_tree_top(struct bounce_zone *bz) 1473{ |
1474 |
|
1471 return (bz->sysctl_tree_top); 1472} 1473 1474static int 1475alloc_bounce_zone(bus_dma_tag_t dmat) 1476{ 1477 struct bounce_zone *bz; 1478 --- 220 unchanged lines hidden --- | 1475 return (bz->sysctl_tree_top); 1476} 1477 1478static int 1479alloc_bounce_zone(bus_dma_tag_t dmat) 1480{ 1481 struct bounce_zone *bz; 1482 --- 220 unchanged lines hidden --- |