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;
}
}