| 1366 | } |
| 1367 | |
| 1368 | void |
| 1369 | bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op) |
| 1370 | { |
| 1371 | struct bounce_page *bpage; |
| 1372 | struct sync_list *sl, *end; |
| 1373 | vm_offset_t datavaddr, tempvaddr; |
| 1374 | |
| 1375 | if (op == BUS_DMASYNC_POSTWRITE) |
| 1376 | return; |
| 1377 | |
| 1378 | /* |
| 1379 | * If the buffer was from user space, it is possible that this is not |
| 1380 | * the same vm map, especially on a POST operation. It's not clear that |
| 1381 | * dma on userland buffers can work at all right now. To be safe, until |
| 1382 | * we're able to test direct userland dma, panic on a map mismatch. |
| 1383 | */ |
| 1384 | if ((bpage = STAILQ_FIRST(&map->bpages)) != NULL) { |
| 1385 | CTR4(KTR_BUSDMA, "%s: tag %p tag flags 0x%x op 0x%x " |
| 1386 | "performing bounce", __func__, dmat, dmat->flags, op); |
| 1387 | |
| 1388 | /* |
| 1389 | * For PREWRITE do a writeback. Clean the caches from the |
| 1390 | * innermost to the outermost levels. |
| 1391 | */ |
| 1392 | if (op & BUS_DMASYNC_PREWRITE) { |
| 1393 | while (bpage != NULL) { |
| 1394 | tempvaddr = 0; |
| 1395 | datavaddr = bpage->datavaddr; |
| 1396 | if (datavaddr == 0) { |
| 1397 | tempvaddr = pmap_quick_enter_page( |
| 1398 | bpage->datapage); |
| 1399 | datavaddr = tempvaddr | bpage->dataoffs; |
| 1400 | } |
| 1401 | bcopy((void *)datavaddr, (void *)bpage->vaddr, |
| 1402 | bpage->datacount); |
| 1403 | if (tempvaddr != 0) |
| 1404 | pmap_quick_remove_page(tempvaddr); |
| 1405 | if ((dmat->flags & BUS_DMA_COHERENT) == 0) |
| 1406 | dcache_wb_poc(bpage->vaddr, |
| 1407 | bpage->busaddr, bpage->datacount); |
| 1408 | bpage = STAILQ_NEXT(bpage, links); |
| 1409 | } |
| 1410 | dmat->bounce_zone->total_bounced++; |
| 1411 | } |
| 1412 | |
| 1413 | /* |
| 1414 | * Do an invalidate for PREREAD unless a writeback was already |
| 1415 | * done above due to PREWRITE also being set. The reason for a |
| 1416 | * PREREAD invalidate is to prevent dirty lines currently in the |
| 1417 | * cache from being evicted during the DMA. If a writeback was |
| 1418 | * done due to PREWRITE also being set there will be no dirty |
| 1419 | * lines and the POSTREAD invalidate handles the rest. The |
| 1420 | * invalidate is done from the innermost to outermost level. If |
| 1421 | * L2 were done first, a dirty cacheline could be automatically |
| 1422 | * evicted from L1 before we invalidated it, re-dirtying the L2. |
| 1423 | */ |
| 1424 | if ((op & BUS_DMASYNC_PREREAD) && !(op & BUS_DMASYNC_PREWRITE)) { |
| 1425 | bpage = STAILQ_FIRST(&map->bpages); |
no test coverage detected