Module Name:    src
Committed By:   skrll
Date:           Tue May 27 15:56:18 UTC 2014

Modified Files:
        src/sys/arch/mips/mips: bus_dma.c

Log Message:
Optimise the BUS_DMASYNC_PREREAD operation by only using wbinv for partial
cachelines. Full cachelines are now invalidated only.

>From the same change in various mips ports not least cobalt.


To generate a diff of this commit:
cvs rdiff -u -r1.30 -r1.31 src/sys/arch/mips/mips/bus_dma.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/mips/mips/bus_dma.c
diff -u src/sys/arch/mips/mips/bus_dma.c:1.30 src/sys/arch/mips/mips/bus_dma.c:1.31
--- src/sys/arch/mips/mips/bus_dma.c:1.30	Wed Feb  5 19:09:06 2014
+++ src/sys/arch/mips/mips/bus_dma.c	Tue May 27 15:56:18 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: bus_dma.c,v 1.30 2014/02/05 19:09:06 christos Exp $	*/
+/*	$NetBSD: bus_dma.c,v 1.31 2014/05/27 15:56:18 skrll Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2001 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.30 2014/02/05 19:09:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bus_dma.c,v 1.31 2014/05/27 15:56:18 skrll Exp $");
 
 #define _MIPS_BUS_DMA_PRIVATE
 
@@ -856,13 +856,27 @@ _bus_dmamap_sync(bus_dma_tag_t t, bus_dm
 			mips_dcache_wbinv_range(vaddr, minlen);
 			break;
 
-		case BUS_DMASYNC_PREREAD:
-#if 1
-			mips_dcache_wbinv_range(vaddr, minlen);
-#else
-			mips_dcache_inv_range(vaddr, minlen);
-#endif
+		case BUS_DMASYNC_PREREAD: {
+			struct mips_cache_info * const mci = &mips_cache_info;
+			vaddr_t start = vaddr;
+			vaddr_t end = vaddr + minlen;
+			vaddr_t preboundary, firstboundary, lastboundary;
+
+			preboundary = start & ~mci->mci_dcache_align_mask;
+			firstboundary = (start + mci->mci_dcache_align_mask)
+			    & ~mci->mci_dcache_align_mask;
+			lastboundary = end & ~mci->mci_dcache_align_mask;
+			if (preboundary < start && preboundary < lastboundary)
+				mips_dcache_wbinv_range(preboundary,
+				    mci->mci_dcache_align);
+			if (firstboundary < lastboundary)
+				mips_dcache_inv_range(firstboundary,
+				    lastboundary - firstboundary);
+			if (lastboundary < end)
+				mips_dcache_wbinv_range(lastboundary,
+				    mci->mci_dcache_align);
 			break;
+		}
 
 		case BUS_DMASYNC_PREWRITE:
 			mips_dcache_wb_range(vaddr, minlen);

Reply via email to