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