Module Name:    src
Committed By:   matt
Date:           Fri Apr 29 22:19:30 UTC 2011

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

Log Message:
simplify.  Don't limit data way size to a page.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/arch/mips/mips/cache_mipsNN.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/cache_mipsNN.c
diff -u src/sys/arch/mips/mips/cache_mipsNN.c:1.13 src/sys/arch/mips/mips/cache_mipsNN.c:1.14
--- src/sys/arch/mips/mips/cache_mipsNN.c:1.13	Sun Feb 20 07:45:47 2011
+++ src/sys/arch/mips/mips/cache_mipsNN.c	Fri Apr 29 22:19:30 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: cache_mipsNN.c,v 1.13 2011/02/20 07:45:47 matt Exp $	*/
+/*	$NetBSD: cache_mipsNN.c,v 1.14 2011/04/29 22:19:30 matt Exp $	*/
 
 /*
  * Copyright 2001 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cache_mipsNN.c,v 1.13 2011/02/20 07:45:47 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cache_mipsNN.c,v 1.14 2011/04/29 22:19:30 matt Exp $");
 
 #include <sys/param.h>
 
@@ -60,7 +60,7 @@
 #define	SYNC	__asm volatile("sync")
 #endif
 
-#if defined(__mips_o32)
+#ifdef __mips_o32
 __asm(".set mips32");
 #else
 __asm(".set mips64");
@@ -68,14 +68,12 @@
 
 static int picache_stride;
 static int picache_loopcount;
-static int pdcache_stride;
-static int pdcache_loopcount;
 
 void
 mipsNN_cache_init(uint32_t config, uint32_t config1)
 {
 	struct mips_cache_info * const mci = &mips_cache_info;
-	int flush_multiple_lines_per_way;
+	bool flush_multiple_lines_per_way;
 
 	flush_multiple_lines_per_way = mci->mci_picache_way_size > PAGE_SIZE;
 	if (config & MIPSNN_CFG_VI) {
@@ -84,7 +82,7 @@
 		 * multiples of the page size with index ops; we just
 		 * need to flush one pages' worth.
 		 */
-		flush_multiple_lines_per_way = 0;
+		flush_multiple_lines_per_way = false;
 	}
 
 	if (flush_multiple_lines_per_way) {
@@ -96,22 +94,12 @@
 		picache_loopcount = mci->mci_picache_ways;
 	}
 
-	if (mci->mci_pdcache_way_size < PAGE_SIZE) {
-		pdcache_stride = mci->mci_pdcache_way_size;
-		pdcache_loopcount = mci->mci_pdcache_ways;
-	} else {
-		pdcache_stride = PAGE_SIZE;
-		pdcache_loopcount = (mci->mci_pdcache_way_size / PAGE_SIZE) *
-		    mci->mci_pdcache_ways;
-	}
 #define CACHE_DEBUG
 #ifdef CACHE_DEBUG
 	if (config & MIPSNN_CFG_VI)
 		printf("  icache is virtual\n");
 	printf("  picache_stride    = %d\n", picache_stride);
 	printf("  picache_loopcount = %d\n", picache_loopcount);
-	printf("  pdcache_stride    = %d\n", pdcache_stride);
-	printf("  pdcache_loopcount = %d\n", pdcache_loopcount);
 #endif
 }
 
@@ -228,6 +216,15 @@
 	va = trunc_line16(va);
 
 	/*
+	 * If we are going to flush more than is in a way, we are flushing
+	 * everything.
+	 */
+	if (eva - va >= mci->mci_picache_way_size) {
+		mipsNN_icache_sync_all_16();
+		return;
+	}
+
+	/*
 	 * GCC generates better code in the loops if we reference local
 	 * copies of these global variables.
 	 */
@@ -238,17 +235,19 @@
 
 	while ((eva - va) >= (8 * 16)) {
 		tmpva = va;
-		for (i = 0; i < loopcount; i++, tmpva += stride)
+		for (i = 0; i < loopcount; i++, tmpva += stride) {
 			cache_r4k_op_8lines_16(tmpva,
 			    CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
+		}
 		va += 8 * 16;
 	}
 
 	while (va < eva) {
 		tmpva = va;
-		for (i = 0; i < loopcount; i++, tmpva += stride)
+		for (i = 0; i < loopcount; i++, tmpva += stride) {
 			cache_op_r4k_line(tmpva,
 			    CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
+		}
 		va += 16;
 	}
 }
@@ -266,14 +265,18 @@
 	 * bits that determine the cache index, and make a KSEG0
 	 * address out of them.
 	 */
-	if (size >= mci->mci_picache_way_size) {
-		va = MIPS_KSEG0_START;
-		eva = va + mci->mci_picache_way_size;
-	} else {
-		va = MIPS_PHYS_TO_KSEG0(va & mci->mci_picache_way_mask);
+	va = MIPS_PHYS_TO_KSEG0(va & mci->mci_picache_way_mask);
+
+	eva = round_line32(va + size);
+	va = trunc_line32(va);
 
-		eva = round_line32(va + size);
-		va = trunc_line32(va);
+	/*
+	 * If we are going to flush more than is in a way, we are flushing
+	 * everything.
+	 */
+	if (eva - va >= mci->mci_picache_way_size) {
+		mipsNN_icache_sync_all_32();
+		return;
 	}
 
 	/*
@@ -287,17 +290,19 @@
 
 	while ((eva - va) >= (8 * 32)) {
 		tmpva = va;
-		for (i = 0; i < loopcount; i++, tmpva += stride)
+		for (i = 0; i < loopcount; i++, tmpva += stride) {
 			cache_r4k_op_8lines_32(tmpva,
 			    CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
+		}
 		va += 8 * 32;
 	}
 
 	while (va < eva) {
 		tmpva = va;
-		for (i = 0; i < loopcount; i++, tmpva += stride)
+		for (i = 0; i < loopcount; i++, tmpva += stride) {
 			cache_op_r4k_line(tmpva,
 			    CACHE_R4K_I|CACHEOP_R4K_INDEX_INV);
+		}
 		va += 32;
 	}
 }
@@ -392,87 +397,115 @@
 	SYNC;
 }
 
-void
-mipsNN_pdcache_wbinv_range_index_16(vaddr_t va, vsize_t size)
+static void
+mipsNN_pdcache_wbinv_range_index_16_intern(vaddr_t va, vaddr_t eva)
 {
-	struct mips_cache_info * const mci = &mips_cache_info;
-	vaddr_t eva, tmpva;
-	int i, stride, loopcount;
-
 	/*
 	 * Since we're doing Index ops, we expect to not be able
 	 * to access the address we've been given.  So, get the
 	 * bits that determine the cache index, and make a KSEG0
 	 * address out of them.
 	 */
-	va = MIPS_PHYS_TO_KSEG0(va & mci->mci_pdcache_way_mask);
+	va = MIPS_PHYS_TO_KSEG0(va);
+	eva = MIPS_PHYS_TO_KSEG0(eva);
 
-	eva = round_line16(va + size);
-	va = trunc_line16(va);
+	for (; (eva - va) >= (8 * 16); va += 8 * 16) {
+		cache_r4k_op_8lines_16(va,
+		    CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
+	}
+
+	for (; va < eva; va += 16) {
+		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
+	}
+}
 
+static void
+mipsNN_pdcache_wbinv_range_index_32_intern(vaddr_t va, vaddr_t eva)
+{
 	/*
-	 * GCC generates better code in the loops if we reference local
-	 * copies of these global variables.
+	 * Since we're doing Index ops, we expect to not be able
+	 * to access the address we've been given.  So, get the
+	 * bits that determine the cache index, and make a KSEG0
+	 * address out of them.
 	 */
-	stride = pdcache_stride;
-	loopcount = pdcache_loopcount;
+	va = MIPS_PHYS_TO_KSEG0(va);
+	eva = MIPS_PHYS_TO_KSEG0(eva);
 
-	while ((eva - va) >= (8 * 16)) {
-		tmpva = va;
-		for (i = 0; i < loopcount; i++, tmpva += stride)
-			cache_r4k_op_8lines_16(tmpva,
-			    CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
-		va += 8 * 16;
+	for (; (eva - va) >= (8 * 32); va += 8 * 32) {
+		cache_r4k_op_8lines_32(va,
+		    CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
 	}
 
-	while (va < eva) {
-		tmpva = va;
-		for (i = 0; i < loopcount; i++, tmpva += stride)
-			cache_op_r4k_line(tmpva,
-			    CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
-		va += 16;
+	for (; va < eva; va += 32) {
+		cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
 	}
 }
 
 void
-mipsNN_pdcache_wbinv_range_index_32(vaddr_t va, vsize_t size)
+mipsNN_pdcache_wbinv_range_index_16(vaddr_t va, vsize_t size)
 {
 	struct mips_cache_info * const mci = &mips_cache_info;
-	vaddr_t eva, tmpva;
-	int i, stride, loopcount;
+	const vaddr_t way_size = mci->mci_pdcache_way_size;
+	const vaddr_t way_mask = way_size - 1;
+	const u_int ways = mci->mci_pdcache_ways;
+	vaddr_t eva;
+
+	va &= way_mask;
+	eva = round_line16(va + size);
+	va = trunc_line16(va);
 
 	/*
-	 * Since we're doing Index ops, we expect to not be able
-	 * to access the address we've been given.  So, get the
-	 * bits that determine the cache index, and make a KSEG0
-	 * address out of them.
+	 * If we are going to flush more than is in a way, we are flushing
+	 * everything.
 	 */
-	va = MIPS_PHYS_TO_KSEG0(va & mci->mci_pdcache_way_mask);
+	if (eva - va >= way_size) {
+		mipsNN_pdcache_wbinv_all_16();
+		return;
+	}
 
+	/*
+	 * Invalidate each way.  If the address range wraps past the end of
+	 * the way, we will be invalidating in two ways but eventually things
+	 * work out since the last way will wrap into the first way.
+	 */
+	for (u_int way = 0; way < ways; way++) {
+		mipsNN_pdcache_wbinv_range_index_16_intern(va, eva);
+		va += way_size;
+		eva += way_size;
+	}
+}
+ 
+void
+mipsNN_pdcache_wbinv_range_index_32(vaddr_t va, vsize_t size)
+{
+	struct mips_cache_info * const mci = &mips_cache_info;
+	const vaddr_t way_size = mci->mci_pdcache_way_size;
+	const vaddr_t way_mask = way_size - 1;
+	const u_int ways = mci->mci_pdcache_ways;
+	vaddr_t eva;
+
+	va &= way_mask;
 	eva = round_line32(va + size);
 	va = trunc_line32(va);
 
 	/*
-	 * GCC generates better code in the loops if we reference local
-	 * copies of these global variables.
+	 * If we are going to flush more than is in a way, we are flushing
+	 * everything.
 	 */
-	stride = pdcache_stride;
-	loopcount = pdcache_loopcount;
-
-	while ((eva - va) >= (8 * 32)) {
-		tmpva = va;
-		for (i = 0; i < loopcount; i++, tmpva += stride)
-			cache_r4k_op_8lines_32(tmpva,
-			    CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
-		va += 8 * 32;
+	if (eva - va >= way_size) {
+		mipsNN_pdcache_wbinv_all_32();
+		return;
 	}
 
-	while (va < eva) {
-		tmpva = va;
-		for (i = 0; i < loopcount; i++, tmpva += stride)
-			cache_op_r4k_line(tmpva,
-			    CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
-		va += 32;
+	/*
+	 * Invalidate each way.  If the address range wraps past the end of
+	 * the way, we will be invalidating in two ways but eventually things
+	 * work out since the last way will wrap into the first way.
+	 */
+	for (u_int way = 0; way < ways; way++) {
+		mipsNN_pdcache_wbinv_range_index_32_intern(va, eva);
+		va += way_size;
+		eva += way_size;
 	}
 }
  

Reply via email to