PERFORCE change 125306 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Sat Aug 18 09:32:38 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=125306
Change 125306 by gonzo at gonzo_jeeves on 2007/08/18 16:31:55
o Flush caches on bus_dma_sync
Affected files ...
.. //depot/projects/mips2/src/sys/mips/mips/busdma_machdep.c#5 edit
Differences ...
==== //depot/projects/mips2/src/sys/mips/mips/busdma_machdep.c#5 (text+ko) ====
@@ -699,18 +699,100 @@
return;
}
-
-
static __inline void
bus_dmamap_sync_buf(void *buf, int len, bus_dmasync_op_t op)
{
- panic("Unimplemented %s at %s:%d\n", __func__, __FILE__, __LINE__);
+ switch (op) {
+ case BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE:
+ mips_dcache_wbinv_range((vm_offset_t)buf, len);
+ break;
+
+ case BUS_DMASYNC_PREREAD:
+#if 1
+ mips_dcache_wbinv_range((vm_offset_t)buf, len);
+#else
+ mips_dcache_inv_range((vm_offset_t)buf, len);
+#endif
+ break;
+
+ case BUS_DMASYNC_PREWRITE:
+ mips_dcache_wb_range((vm_offset_t)buf, len);
+ break;
+ }
}
void
_bus_dmamap_sync(bus_dma_tag_t dmat, bus_dmamap_t map, bus_dmasync_op_t op)
{
+ struct mbuf *m;
+ struct uio *uio;
+ int resid;
+ struct iovec *iov;
+
+
+ /*
+ * Mixing PRE and POST operations is not allowed.
+ */
+ if ((op & (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)) != 0 &&
+ (op & (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)) != 0)
+ panic("_bus_dmamap_sync: mix PRE and POST");
+
+ /*
+ * Since we're dealing with a virtually-indexed, write-back
+ * cache, we need to do the following things:
+ *
+ * PREREAD -- Invalidate D-cache. Note we might have
+ * to also write-back here if we have to use an Index
+ * op, or if the buffer start/end is not cache-line aligned.
+ *
+ * PREWRITE -- Write-back the D-cache. If we have to use
+ * an Index op, we also have to invalidate. Note that if
+ * we are doing PREREAD|PREWRITE, we can collapse everything
+ * into a single op.
+ *
+ * POSTREAD -- Nothing.
+ *
+ * POSTWRITE -- Nothing.
+ */
+
+ /*
+ * Flush the write buffer.
+ * XXX Is this always necessary?
+ */
+ mips_wbflush();
- /* XXXMIPS: flush caches or whatever */
+ op &= (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+ if (op == 0)
+ return;
+
+ CTR3(KTR_BUSDMA, "%s: op %x flags %x", __func__, op, map->flags);
+ switch(map->flags & DMAMAP_TYPE_MASK) {
+ case DMAMAP_LINEAR:
+ bus_dmamap_sync_buf(map->buffer, map->len, op);
+ break;
+ case DMAMAP_MBUF:
+ m = map->buffer;
+ while (m) {
+ if (m->m_len > 0)
+ bus_dmamap_sync_buf(m->m_data, m->m_len, op);
+ m = m->m_next;
+ }
+ break;
+ case DMAMAP_UIO:
+ uio = map->buffer;
+ iov = uio->uio_iov;
+ resid = uio->uio_resid;
+ for (int i = 0; i < uio->uio_iovcnt && resid != 0; i++) {
+ bus_size_t minlen = resid < iov[i].iov_len ? resid :
+ iov[i].iov_len;
+ if (minlen > 0) {
+ bus_dmamap_sync_buf(iov[i].iov_base, minlen, op);
+ resid -= minlen;
+ }
+ }
+ break;
+ default:
+ break;
+ }
}
More information about the p4-projects
mailing list