summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2006-05-31 15:50:33 +0000
committercognet <cognet@FreeBSD.org>2006-05-31 15:50:33 +0000
commit25b7dd01d0df23ed683f2ee8001d050bc7350d3d (patch)
treeec2de188b090a526ab1068e35470386facb2720d /sys/arm
parente0f17fb7e891725b511ed4b9b776c35ed80d5c00 (diff)
downloadFreeBSD-src-25b7dd01d0df23ed683f2ee8001d050bc7350d3d.zip
FreeBSD-src-25b7dd01d0df23ed683f2ee8001d050bc7350d3d.tar.gz
If our buffer is not aligned on the cache line size, write back/invalidate
the first and last cache line in PREREAD, and just invalidate the cache lines in POSTREAD, instead of write-back/invalidating in POSTREAD, which could lead to stale data overriding what has been transfered by DMA.
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/arm/busdma_machdep.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/sys/arm/arm/busdma_machdep.c b/sys/arm/arm/busdma_machdep.c
index f3f89ae..7ada577 100644
--- a/sys/arm/arm/busdma_machdep.c
+++ b/sys/arm/arm/busdma_machdep.c
@@ -806,13 +806,16 @@ bus_dmamap_sync_buf(void *buf, int len, bus_dmasync_op_t op)
if (op & BUS_DMASYNC_PREWRITE)
cpu_dcache_wb_range((vm_offset_t)buf, len);
- if (op & BUS_DMASYNC_POSTREAD) {
- if ((((vm_offset_t)buf | len) & arm_dcache_align_mask) == 0)
- cpu_dcache_inv_range((vm_offset_t)buf, len);
- else
- cpu_dcache_wbinv_range((vm_offset_t)buf, len);
-
+ if (op & BUS_DMASYNC_PREREAD) {
+ if ((vm_offset_t)buf & arm_dcache_align_mask)
+ cpu_dcache_wbinv_range((vm_offset_t)buf &
+ ~arm_dcache_align_mask, arm_dcache_align);
+ if (((vm_offset_t)buf + len) & arm_dcache_align_mask)
+ cpu_dcache_wbinv_range(((vm_offset_t)buf + len) &
+ ~arm_dcache_align_mask, arm_dcache_align);
}
+ if (op & BUS_DMASYNC_POSTREAD)
+ cpu_dcache_inv_range((vm_offset_t)buf, len);
}
void
@@ -823,7 +826,7 @@ _bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
int resid;
struct iovec *iov;
- if (!(op & (BUS_DMASYNC_PREWRITE | BUS_DMASYNC_POSTREAD)))
+ if (op == BUS_DMASYNC_POSTWRITE)
return;
if (map->flags & DMAMAP_COHERENT)
return;
OpenPOWER on IntegriCloud