Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 18 Aug 2007 16:32:37 GMT
From:      Oleksandr Tymoshenko <gonzo@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 125306 for review
Message-ID:  <200708181632.l7IGWbZZ047217@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=125306

Change 125306 by gonzo@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;
+	}
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708181632.l7IGWbZZ047217>