Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/mips/mips simplify. Don't limit data way size to a...
details: https://anonhg.NetBSD.org/src/rev/c3f5c5b153ac
branches: trunk
changeset: 764660:c3f5c5b153ac
user: matt <matt%NetBSD.org@localhost>
date: Fri Apr 29 22:19:30 2011 +0000
description:
simplify. Don't limit data way size to a page.
diffstat:
sys/arch/mips/mips/cache_mipsNN.c | 191 ++++++++++++++++++++++---------------
1 files changed, 112 insertions(+), 79 deletions(-)
diffs (truncated from 328 to 300 lines):
diff -r 32f25a4bd83a -r c3f5c5b153ac sys/arch/mips/mips/cache_mipsNN.c
--- a/sys/arch/mips/mips/cache_mipsNN.c Fri Apr 29 22:18:53 2011 +0000
+++ b/sys/arch/mips/mips/cache_mipsNN.c Fri Apr 29 22:19:30 2011 +0000
@@ -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);
+ eva = MIPS_PHYS_TO_KSEG0(eva);
+ 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)
+{
/*
* 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);
+
+ for (; (eva - va) >= (8 * 32); va += 8 * 32) {
+ cache_r4k_op_8lines_32(va,
+ CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
+ }
+ for (; va < eva; va += 32) {
+ cache_op_r4k_line(va, CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV);
+ }
+}
+
+void
+mipsNN_pdcache_wbinv_range_index_16(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_line16(va + size);
va = trunc_line16(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 * 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;
+ if (eva - va >= way_size) {
+ mipsNN_pdcache_wbinv_all_16();
+ 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 += 16;
+ /*
+ * 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;
- 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;
- /*
- * 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 &= 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)) {
Home |
Main Index |
Thread Index |
Old Index