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