| 1306 | } |
| 1307 | |
| 1308 | static void |
| 1309 | dma_dcache_sync(struct sync_list *sl, bus_dmasync_op_t op) |
| 1310 | { |
| 1311 | uint32_t len, offset; |
| 1312 | vm_page_t m; |
| 1313 | vm_paddr_t pa; |
| 1314 | vm_offset_t va, tempva; |
| 1315 | bus_size_t size; |
| 1316 | |
| 1317 | offset = sl->paddr & PAGE_MASK; |
| 1318 | m = sl->pages; |
| 1319 | size = sl->datacount; |
| 1320 | pa = sl->paddr; |
| 1321 | |
| 1322 | for ( ; size != 0; size -= len, pa += len, offset = 0, ++m) { |
| 1323 | tempva = 0; |
| 1324 | if (sl->vaddr == 0) { |
| 1325 | len = min(PAGE_SIZE - offset, size); |
| 1326 | tempva = pmap_quick_enter_page(m); |
| 1327 | va = tempva | offset; |
| 1328 | KASSERT(pa == (VM_PAGE_TO_PHYS(m) | offset), |
| 1329 | ("unexpected vm_page_t phys: 0x%08x != 0x%08x", |
| 1330 | VM_PAGE_TO_PHYS(m) | offset, pa)); |
| 1331 | } else { |
| 1332 | len = sl->datacount; |
| 1333 | va = sl->vaddr; |
| 1334 | } |
| 1335 | |
| 1336 | switch (op) { |
| 1337 | case BUS_DMASYNC_PREWRITE: |
| 1338 | case BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD: |
| 1339 | dcache_wb_poc(va, pa, len); |
| 1340 | break; |
| 1341 | case BUS_DMASYNC_PREREAD: |
| 1342 | /* |
| 1343 | * An mbuf may start in the middle of a cacheline. There |
| 1344 | * will be no cpu writes to the beginning of that line |
| 1345 | * (which contains the mbuf header) while dma is in |
| 1346 | * progress. Handle that case by doing a writeback of |
| 1347 | * just the first cacheline before invalidating the |
| 1348 | * overall buffer. Any mbuf in a chain may have this |
| 1349 | * misalignment. Buffers which are not mbufs bounce if |
| 1350 | * they are not aligned to a cacheline. |
| 1351 | */ |
| 1352 | dma_preread_safe(va, pa, len); |
| 1353 | break; |
| 1354 | case BUS_DMASYNC_POSTREAD: |
| 1355 | case BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE: |
| 1356 | dcache_inv_poc(va, pa, len); |
| 1357 | break; |
| 1358 | default: |
| 1359 | panic("unsupported combination of sync operations: " |
| 1360 | "0x%08x\n", op); |
| 1361 | } |
| 1362 | |
| 1363 | if (tempva != 0) |
| 1364 | pmap_quick_remove_page(tempva); |
| 1365 | } |
no test coverage detected