Module Name: src
Committed By: matt
Date: Tue Dec 27 03:39:41 UTC 2011
Modified Files:
src/sys/arch/mips/mips [matt-nb5-mips64]: cache.c cache_mipsNN.c
Log Message:
Rework (rewrite) the cache code for MIPS32/MIPS64. Use an assembly stub
for generate the cache instructions. Add some more intern routines so that
cache_mipsNN.c only had the "generic" all/index routines.
To generate a diff of this commit:
cvs rdiff -u -r1.33.96.8 -r1.33.96.9 src/sys/arch/mips/mips/cache.c
cvs rdiff -u -r1.11.78.6 -r1.11.78.7 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.c
diff -u src/sys/arch/mips/mips/cache.c:1.33.96.8 src/sys/arch/mips/mips/cache.c:1.33.96.9
--- src/sys/arch/mips/mips/cache.c:1.33.96.8 Fri Dec 23 22:47:26 2011
+++ src/sys/arch/mips/mips/cache.c Tue Dec 27 03:39:40 2011
@@ -1006,18 +1006,22 @@ mips_config_cache_modern(uint32_t cpu_id
switch (mci->mci_picache_line_size) {
case 16:
- mco->mco_icache_sync_all = mipsNN_icache_sync_all_16;
- mco->mco_icache_sync_range =
- mipsNN_icache_sync_range_16;
- mco->mco_icache_sync_range_index =
- mipsNN_icache_sync_range_index_16;
+ /* used internally by mipsNN_picache_sync_range */
+ mco->mco_intern_icache_sync_range =
+ cache_r4k_icache_hit_inv_16;
+
+ /* used internally by mipsNN_picache_sync_range_index */
+ mco->mco_intern_icache_sync_range_index =
+ cache_r4k_icache_index_inv_16;
break;
case 32:
- mco->mco_icache_sync_all = mipsNN_icache_sync_all_32;
- mco->mco_icache_sync_range =
- mipsNN_icache_sync_range_32;
- mco->mco_icache_sync_range_index =
- mipsNN_icache_sync_range_index_32;
+ /* used internally by mipsNN_picache_sync_range */
+ mco->mco_intern_icache_sync_range =
+ cache_r4k_icache_hit_inv_32;
+
+ /* used internally by mipsNN_picache_sync_range_index */
+ mco->mco_intern_icache_sync_range_index =
+ cache_r4k_icache_index_inv_32;
break;
#ifdef MIPS_DISABLE_L1_CACHE
case 0:
@@ -1033,59 +1037,65 @@ mips_config_cache_modern(uint32_t cpu_id
mci->mci_picache_line_size);
}
+ mco->mco_icache_sync_all = mipsNN_picache_sync_all;
+ mco->mco_icache_sync_range = mipsNN_picache_sync_range;
+ mco->mco_icache_sync_range_index = mipsNN_picache_sync_range_index;
+
switch (mci->mci_pdcache_line_size) {
case 16:
- mco->mco_pdcache_wbinv_all =
- mco->mco_intern_pdcache_wbinv_all =
- mipsNN_pdcache_wbinv_all_16;
mco->mco_pdcache_wbinv_range =
- mipsNN_pdcache_wbinv_range_16;
- mco->mco_pdcache_wbinv_range_index =
- mco->mco_intern_pdcache_wbinv_range_index =
- mipsNN_pdcache_wbinv_range_index_16;
+ cache_r4k_pdcache_hit_wb_inv_16;
mco->mco_pdcache_inv_range =
- mipsNN_pdcache_inv_range_16;
+ cache_r4k_pdcache_hit_inv_16;
mco->mco_pdcache_wb_range =
- mco->mco_intern_pdcache_wb_range =
- mipsNN_pdcache_wb_range_16;
+ cache_r4k_pdcache_hit_wb_16;
+
+ /* used internally by mipsNN_pdcache_wbinv_range_index */
+ mco->mco_intern_pdcache_wbinv_range_index =
+ cache_r4k_pdcache_index_wb_inv_16;
break;
case 32:
- mco->mco_pdcache_wbinv_all =
- mco->mco_intern_pdcache_wbinv_all =
- mipsNN_pdcache_wbinv_all_32;
mco->mco_pdcache_wbinv_range =
- mipsNN_pdcache_wbinv_range_32;
- mco->mco_pdcache_wbinv_range_index =
- mco->mco_intern_pdcache_wbinv_range_index =
- mipsNN_pdcache_wbinv_range_index_32;
+ cache_r4k_pdcache_hit_wb_inv_32;
mco->mco_pdcache_inv_range =
- mipsNN_pdcache_inv_range_32;
+ cache_r4k_pdcache_hit_inv_32;
mco->mco_pdcache_wb_range =
- mco->mco_intern_pdcache_wb_range =
- mipsNN_pdcache_wb_range_32;
+ cache_r4k_pdcache_hit_wb_32;
+
+ /* used internally by mipsNN_pdcache_wbinv_range_index */
+ mco->mco_intern_pdcache_wbinv_range_index =
+ cache_r4k_pdcache_index_wb_inv_32;
break;
#ifdef MIPS_DISABLE_L1_CACHE
case 0:
mco->mco_pdcache_wbinv_all = cache_noop;
- mco->mco_intern_pdcache_wbinv_all = cache_noop;
mco->mco_pdcache_wbinv_range =
(void (*)(vaddr_t, vsize_t))cache_noop;
mco->mco_pdcache_wbinv_range_index =
(void (*)(vaddr_t, vsize_t))cache_noop;
- mco->mco_intern_pdcache_wbinv_range_index =
- (void (*)(vaddr_t, vsize_t))cache_noop;
mco->mco_pdcache_inv_range =
(void (*)(vaddr_t, vsize_t))cache_noop;
mco->mco_pdcache_wb_range =
(void (*)(vaddr_t, vsize_t))cache_noop;
- mco->mco_intern_pdcache_wb_range =
- (void (*)(vaddr_t, vsize_t))cache_noop;
break;
#endif
default:
panic("no Dcache ops for %d byte lines",
mci->mci_pdcache_line_size);
}
+
+ mco->mco_pdcache_wbinv_all =
+ mipsNN_pdcache_wbinv_all;
+ mco->mco_pdcache_wbinv_range_index =
+ mipsNN_pdcache_wbinv_range_index;
+
+ mco->mco_intern_pdcache_sync_all =
+ mco->mco_pdcache_wbinv_all;
+ mco->mco_intern_pdcache_sync_range_index =
+ mco->mco_intern_pdcache_wbinv_range_index;
+ mco->mco_intern_pdcache_sync_range =
+ mco->mco_pdcache_wb_range;
+
if (MIPSNN_CFG1_M & cfg1) {
uint32_t cfg2 = mipsNN_cp0_config2_read();
@@ -1176,7 +1186,7 @@ mips_config_cache_modern(uint32_t cpu_id
*/
if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_RMI) {
mco->mco_pdcache_wb_range = mco->mco_pdcache_wbinv_range;
- mco->mco_intern_pdcache_wb_range = mco->mco_pdcache_wbinv_range;
+ mco->mco_intern_pdcache_sync_range = mco->mco_pdcache_wbinv_range;
if (MIPSNN_GET(CFG_AR, cfg) == MIPSNN_CFG_AR_REV2) {
mci->mci_pdcache_write_through = true;
mci->mci_sdcache_write_through = false;
@@ -1204,9 +1214,11 @@ mips_config_cache_modern(uint32_t cpu_id
/* Instruction Alias Removal Present */
mci->mci_icache_virtual_alias = false;
}
+#if 0
} else {
KASSERT(mci->mci_pdcache_way_size <= PAGE_SIZE);
KASSERT(mci->mci_picache_way_size <= PAGE_SIZE);
+#endif
}
#endif
}
@@ -1242,11 +1254,11 @@ mips_config_cache_modern(uint32_t cpu_id
#ifdef CACHE_DEBUG
printf(" Icache is coherent against Dcache\n");
#endif
- mco->mco_intern_pdcache_wbinv_all =
+ mco->mco_intern_pdcache_sync_all =
cache_noop;
- mco->mco_intern_pdcache_wbinv_range_index =
+ mco->mco_intern_pdcache_sync_range_index =
(void (*)(vaddr_t, vsize_t))cache_noop;
- mco->mco_intern_pdcache_wb_range =
+ mco->mco_intern_pdcache_sync_range =
(void (*)(vaddr_t, vsize_t))cache_noop;
}
}
Index: src/sys/arch/mips/mips/cache_mipsNN.c
diff -u src/sys/arch/mips/mips/cache_mipsNN.c:1.11.78.6 src/sys/arch/mips/mips/cache_mipsNN.c:1.11.78.7
--- src/sys/arch/mips/mips/cache_mipsNN.c:1.11.78.6 Sat Dec 24 09:52:44 2011
+++ src/sys/arch/mips/mips/cache_mipsNN.c Tue Dec 27 03:39:41 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: cache_mipsNN.c,v 1.11.78.6 2011/12/24 09:52:44 matt Exp $ */
+/* $NetBSD: cache_mipsNN.c,v 1.11.78.7 2011/12/27 03:39:41 matt Exp $ */
/*
* Copyright 2001 Wasabi Systems, Inc.
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cache_mipsNN.c,v 1.11.78.6 2011/12/24 09:52:44 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cache_mipsNN.c,v 1.11.78.7 2011/12/27 03:39:41 matt Exp $");
#include <sys/param.h>
@@ -62,47 +62,6 @@ __asm(".set mips32");
__asm(".set mips64");
#endif
-static inline void
-mipsNN_cache_op_intern(size_t line_size, u_int op, vaddr_t va, vsize_t size)
-{
- vaddr_t eva;
-
- eva = round_line(va + size, line_size);
- va = trunc_line(va, line_size);
-
- for (; va + 32 * line_size <= eva; va += 32 * line_size) {
- cache_r4k_op_32lines_NN(line_size, va, op);
- }
-
- for (; va + 8 * line_size <= eva; va += 8 * line_size) {
- cache_r4k_op_8lines_NN(line_size, va, op);
- }
-
- for (;va < eva; va += line_size) {
- cache_op_r4k_line(va, op);
- }
-
- SYNC;
-}
-
-static void
-mipsNN_intern_icache_index_inv_16(vaddr_t va, vaddr_t eva)
-{
- const u_int op = CACHE_R4K_I|CACHEOP_R4K_INDEX_INV;
- const size_t line_size = 16;
-
- mipsNN_cache_op_intern(line_size, op, va, eva - va);
-}
-
-static void
-mipsNN_intern_icache_index_inv_32(vaddr_t va, vaddr_t eva)
-{
- const u_int op = CACHE_R4K_I|CACHEOP_R4K_INDEX_INV;
- const size_t line_size = 32;
-
- mipsNN_cache_op_intern(line_size, op, va, eva - va);
-}
-
void
mipsNN_cache_init(uint32_t config, uint32_t config1)
{
@@ -110,75 +69,61 @@ mipsNN_cache_init(uint32_t config, uint3
}
void
-mipsNN_icache_sync_all_16(void)
+mipsNN_picache_sync_all(void)
{
struct mips_cache_info * const mci = &mips_cache_info;
- vaddr_t va = MIPS_KSEG0_START;
- const vaddr_t eva = va + mci->mci_picache_size;
/*
* Since we're hitting the whole thing, we don't have to
* worry about the N different "ways".
*/
- mips_intern_dcache_wbinv_all();
-
- mipsNN_intern_icache_index_inv_16(va, eva);
+ mips_intern_dcache_sync_all();
+ mips_intern_icache_sync_range_index(MIPS_KSEG0_START,
+ mci->mci_picache_size);
}
void
-mipsNN_icache_sync_all_32(void)
+mipsNN_pdcache_wbinv_all(void)
{
struct mips_cache_info * const mci = &mips_cache_info;
- vaddr_t va = MIPS_KSEG0_START;
- const vaddr_t eva = va + mci->mci_picache_size;
/*
* Since we're hitting the whole thing, we don't have to
* worry about the N different "ways".
*/
- mips_intern_dcache_wbinv_all();
-
- mipsNN_intern_icache_index_inv_32(va, eva);
+ mips_intern_pdcache_wbinv_range_index(MIPS_KSEG0_START,
+ mci->mci_pdcache_size);
}
void
-mipsNN_icache_sync_range_16(vaddr_t va, vsize_t size)
+mipsNN_sdcache_wbinv_all(void)
{
- const u_int op = CACHE_R4K_I|CACHEOP_R4K_HIT_INV;
- const size_t line_size = 16;
- vaddr_t eva;
-
- eva = round_line(va + size, line_size);
- va = trunc_line(va, line_size);
-
- mips_intern_dcache_wb_range(va, eva - va);
+ struct mips_cache_info * const mci = &mips_cache_info;
- mipsNN_cache_op_intern(line_size, op, va, eva - va);
+ /*
+ * Since we're hitting the whole thing, we don't have to
+ * worry about the N different "ways".
+ */
+ mips_intern_sdcache_wbinv_range_index(MIPS_KSEG0_START,
+ mci->mci_sdcache_size);
}
void
-mipsNN_icache_sync_range_32(vaddr_t va, vsize_t size)
+mipsNN_picache_sync_range(vaddr_t va, vsize_t size)
{
- const u_int op = CACHE_R4K_I|CACHEOP_R4K_HIT_INV;
- const size_t line_size = 32;
- vaddr_t eva;
-
- eva = round_line(va + size, line_size);
- va = trunc_line(va, line_size);
-
- mips_intern_dcache_wb_range(va, eva - va);
- mipsNN_cache_op_intern(line_size, op, va, eva - va);
+ mips_intern_dcache_sync_range(va, size);
+ mips_intern_icache_sync_range(va, size);
}
void
-mipsNN_icache_sync_range_index_16(vaddr_t va, vsize_t size)
+mipsNN_picache_sync_range_index(vaddr_t va, vsize_t size)
{
struct mips_cache_info * const mci = &mips_cache_info;
+ const size_t ways = mci->mci_picache_ways;
+ const size_t line_size = mci->mci_picache_line_size;
const size_t way_size = mci->mci_picache_way_size;
const size_t way_mask = way_size - 1;
- const size_t ways = mci->mci_picache_ways;
- const size_t line_size = 16;
vaddr_t eva;
/*
@@ -191,33 +136,33 @@ mipsNN_icache_sync_range_index_16(vaddr_
eva = round_line(va + size, line_size);
va = trunc_line(va, line_size);
+ size = eva - va;
/*
* If we are going to flush more than is in a way (or the stride
* need for that way), we are flushing everything.
*/
- if (va + way_size >= eva) {
- mipsNN_icache_sync_all_16();
+ if (size >= way_size) {
+ mipsNN_picache_sync_all();
return;
}
- mips_intern_dcache_wbinv_range_index(va, eva - va);
-
for (size_t way = 0; way < ways; way++) {
- mipsNN_intern_icache_index_inv_16(va, eva);
+ mips_intern_dcache_sync_range_index(va, size);
+ mips_intern_icache_sync_range_index(va, size);
va += way_size;
eva += way_size;
}
}
void
-mipsNN_icache_sync_range_index_32(vaddr_t va, vsize_t size)
+mipsNN_pdcache_wbinv_range_index(vaddr_t va, vsize_t size)
{
struct mips_cache_info * const mci = &mips_cache_info;
- const size_t way_size = mci->mci_picache_way_size;
- const size_t way_mask = way_size - 1;
- const size_t ways = mci->mci_picache_ways;
- const size_t line_size = 32;
+ const size_t ways = mci->mci_pdcache_ways;
+ const size_t line_size = mci->mci_pdcache_line_size;
+ const vaddr_t way_size = mci->mci_pdcache_way_size;
+ const vaddr_t way_mask = way_size - 1;
vaddr_t eva;
/*
@@ -227,126 +172,17 @@ mipsNN_icache_sync_range_index_32(vaddr_
* address out of them.
*/
va = MIPS_PHYS_TO_KSEG0(va & way_mask);
-
- eva = round_line(va + size, line_size);
- va = trunc_line(va, line_size);
-
- /*
- * If we are going to flush more than is in a way (or the stride
- * need for that way), we are flushing everything.
- */
- if (va + way_size >= eva) {
- mipsNN_icache_sync_all_32();
- return;
- }
-
- mips_intern_dcache_wbinv_range_index(va, eva - va);
-
- for (size_t way = 0; way < ways; way++) {
- mipsNN_intern_icache_index_inv_32(va, eva);
- va += way_size;
- eva += way_size;
- }
-}
-
-void
-mipsNN_pdcache_wbinv_all_16(void)
-{
- struct mips_cache_info * const mci = &mips_cache_info;
- const u_int op = CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV;
- const size_t line_size = 16;
-
- vaddr_t va = MIPS_KSEG0_START;
- const vaddr_t eva = va + mci->mci_pdcache_size;
-
- /*
- * Since we're hitting the whole thing, we don't have to
- * worry about the N different "ways".
- */
- for (; va < eva; va += 32 * line_size) {
- cache_r4k_op_32lines_NN(line_size, va, op);
- }
-
- SYNC;
-}
-
-void
-mipsNN_pdcache_wbinv_all_32(void)
-{
- struct mips_cache_info * const mci = &mips_cache_info;
- const u_int op = CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV;
- const size_t line_size = 32;
-
- vaddr_t va = MIPS_KSEG0_START;
- const vaddr_t eva = va + mci->mci_pdcache_size;
-
- /*
- * Since we're hitting the whole thing, we don't have to
- * worry about the N different "ways".
- */
- for (; va < eva; va += 32 * line_size) {
- cache_r4k_op_32lines_NN(line_size, va, op);
- }
-
- SYNC;
-}
-
-static void
-mipsNN_pdcache_wbinv_range_index_16_intern(vaddr_t va, vaddr_t eva)
-{
- const u_int op = CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV;
- const size_t line_size = 16;
-
- /*
- * 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);
-
- mipsNN_cache_op_intern(line_size, op, va, eva - va);
-}
-
-static void
-mipsNN_pdcache_wbinv_range_index_32_intern(vaddr_t va, vaddr_t eva)
-{
- const u_int op = CACHE_R4K_D|CACHEOP_R4K_INDEX_WB_INV;
- const size_t line_size = 32;
-
- /*
- * 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);
-
- mipsNN_cache_op_intern(line_size, op, va, eva - va);
-}
-
-void
-mipsNN_pdcache_wbinv_range_index_16(vaddr_t va, vsize_t size)
-{
- struct mips_cache_info * const mci = &mips_cache_info;
- const size_t ways = mci->mci_pdcache_ways;
- const vaddr_t way_size = mci->mci_pdcache_way_size;
- const vaddr_t way_mask = way_size - 1;
- const size_t line_size = 16;
- vaddr_t eva;
-
- va &= way_mask;
eva = round_line(va + size, line_size);
va = trunc_line(va, line_size);
+ size = eva - va;
/*
* If we are going to flush more than is in a way, we are flushing
* everything.
*/
- if (va + way_size >= eva) {
- mipsNN_pdcache_wbinv_all_16();
+ if (size >= way_size) {
+ mips_intern_pdcache_wbinv_range_index(MIPS_KSEG0_START,
+ mci->mci_pdcache_size);
return;
}
@@ -356,32 +192,40 @@ mipsNN_pdcache_wbinv_range_index_16(vadd
* work out since the last way will wrap into the first way.
*/
for (size_t way = 0; way < ways; way++) {
- mipsNN_pdcache_wbinv_range_index_16_intern(va, eva);
+ mips_intern_pdcache_wbinv_range_index(va, size);
va += way_size;
eva += way_size;
}
}
-
+
void
-mipsNN_pdcache_wbinv_range_index_32(vaddr_t va, vsize_t size)
+mipsNN_sdcache_wbinv_range_index(vaddr_t va, vsize_t size)
{
struct mips_cache_info * const mci = &mips_cache_info;
- const size_t ways = mci->mci_pdcache_ways;
- const vaddr_t way_size = mci->mci_pdcache_way_size;
+ const size_t ways = mci->mci_sdcache_ways;
+ const size_t line_size = mci->mci_sdcache_line_size;
+ const vaddr_t way_size = mci->mci_sdcache_way_size;
const vaddr_t way_mask = way_size - 1;
- const size_t line_size = 32;
vaddr_t eva;
- va &= way_mask;
+ /*
+ * 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 & way_mask);
eva = round_line(va + size, line_size);
va = trunc_line(va, line_size);
+ size = eva - va;
/*
* If we are going to flush more than is in a way, we are flushing
* everything.
*/
- if (va + way_size >= eva) {
- mipsNN_pdcache_wbinv_all_32();
+ if (size >= way_size) {
+ mips_intern_sdcache_wbinv_range_index(MIPS_KSEG0_START,
+ mci->mci_sdcache_size);
return;
}
@@ -391,62 +235,8 @@ mipsNN_pdcache_wbinv_range_index_32(vadd
* work out since the last way will wrap into the first way.
*/
for (size_t way = 0; way < ways; way++) {
- mipsNN_pdcache_wbinv_range_index_32_intern(va, eva);
+ mips_intern_sdcache_wbinv_range_index(va, size);
va += way_size;
eva += way_size;
}
}
-
-void
-mipsNN_pdcache_wbinv_range_16(vaddr_t va, vsize_t size)
-{
- const u_int op = CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV;
- const size_t line_size = 16;
-
- mipsNN_cache_op_intern(line_size, op, va, size);
-}
-
-void
-mipsNN_pdcache_wbinv_range_32(vaddr_t va, vsize_t size)
-{
- const u_int op = CACHE_R4K_D|CACHEOP_R4K_HIT_WB_INV;
- const size_t line_size = 32;
-
- mipsNN_cache_op_intern(line_size, op, va, size);
-}
-
-void
-mipsNN_pdcache_inv_range_16(vaddr_t va, vsize_t size)
-{
- const u_int op = CACHE_R4K_D|CACHEOP_R4K_HIT_INV;
- const size_t line_size = 16;
-
- mipsNN_cache_op_intern(line_size, op, va, size);
-}
-
-void
-mipsNN_pdcache_inv_range_32(vaddr_t va, vsize_t size)
-{
- const u_int op = CACHE_R4K_D|CACHEOP_R4K_HIT_INV;
- const size_t line_size = 32;
-
- mipsNN_cache_op_intern(line_size, op, va, size);
-}
-
-void
-mipsNN_pdcache_wb_range_16(vaddr_t va, vsize_t size)
-{
- const u_int op = CACHE_R4K_D|CACHEOP_R4K_HIT_WB;
- const size_t line_size = 16;
-
- mipsNN_cache_op_intern(line_size, op, va, size);
-}
-
-void
-mipsNN_pdcache_wb_range_32(vaddr_t va, vsize_t size)
-{
- const u_int op = CACHE_R4K_D|CACHEOP_R4K_HIT_WB;
- const size_t line_size = 32;
-
- mipsNN_cache_op_intern(line_size, op, va, size);
-}