busdma problem
Andrew Thompson
thompsa at FreeBSD.org
Thu Jan 29 23:56:30 PST 2009
Hi,
I am having an issue with busdma when bounce buffers are used. I have
patched _bus_dmamap_sync_bp() to print out the details when a bounce
happens and also print the driver buffer before and after.
During normal dma everything is fine,
Before: 0xc7c1ab40 data=c1:4b:a4:80:c0:5d:ed:78:00:00:08:0d:c1:1f:46:78:00:00:20:02:00:00:20:02:
[...do dma...]
After: 0xc7c1ab40 data=2c:03:4e:00:6f:00:76:00:61:00:74:00:65:00:6c:00:20:00:57:00:69:00:72:00:
The buffer 2c:03:4e:00:... is the correct response from the hardware.
When a bounce buffer is used I see the correct data come in and be
bcopy'd to my memory region but it is not visible when read later.
Before: 0xc7c29b40 data=c1:50:19:00:c0:5d:ed:f8:00:00:08:0d:c1:1f:46:78:00:00:20:02:00:00:20:02:
dma bounced 0x1271000 -> 0xc7c29b40 len=193 data=2c:03:4e:00:6f:00:76:00:61:00:74:00:65:00:6c:00:20:00:57:00:69:00:72:00:
After: 0xc7c29b40 data=c1:50:19:00:c0:5d:ed:f8:00:00:08:0d:c1:1f:46:78:00:00:20:02:00:00:20:02:
This is on an xscale ixp425 with 128m memory, the PCI dma tag is limited
to 64m.
Andrew
Index: src/sys/arm/arm/busdma_machdep.c
===================================================================
--- src/sys/arm/arm/busdma_machdep.c (revision 13717)
+++ src/sys/arm/arm/busdma_machdep.c (working copy)
@@ -1128,6 +1128,19 @@
}
static void
+dbgprint_safe(const uint8_t *buf, int len)
+{
+ const uint8_t *p;
+ int i;
+
+ if (len > 24)
+ len = 24;
+
+ for (i = 0, p = buf; i < len; i++, p++)
+ printf("%02x:", *p);
+}
+
+static void
_bus_dmamap_sync_bp(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
{
struct bounce_page *bpage;
@@ -1144,6 +1157,7 @@
cpu_l2cache_wb_range(bpage->vaddr,
bpage->datacount);
}
+ dmat->bounce_zone->total_bounced++;
}
if (op & BUS_DMASYNC_POSTREAD) {
if (bpage->vaddr_nocache == 0) {
@@ -1155,6 +1169,12 @@
bcopy((void *)(bpage->vaddr_nocache != 0 ?
bpage->vaddr_nocache : bpage->vaddr),
(void *)bpage->datavaddr, bpage->datacount);
+ printf("dma bounced %p -> %p len=%d data=",
+ (void *)bpage->busaddr, (void *)bpage->datavaddr,
+ bpage->datacount);
+ dbgprint_safe((void *)bpage->datavaddr, bpage->datacount);
+ printf("\n");
+ dmat->bounce_zone->total_bounced++;
}
}
}
More information about the freebsd-arm
mailing list