diff --git a/sys/arch/mips/mips/cache.c b/sys/arch/mips/mips/cache.c index b1f0315d6bdc..8d87444fd195 100644 --- a/sys/arch/mips/mips/cache.c +++ b/sys/arch/mips/mips/cache.c @@ -1,4 +1,4 @@ -/* $NetBSD: cache.c,v 1.24 2003/12/21 07:59:25 nisimura Exp $ */ +/* $NetBSD: cache.c,v 1.25 2004/12/13 08:39:21 sekiya Exp $ */ /* * Copyright 2001, 2002 Wasabi Systems, Inc. @@ -68,7 +68,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.24 2003/12/21 07:59:25 nisimura Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.25 2004/12/13 08:39:21 sekiya Exp $"); #include "opt_cputype.h" #include "opt_mips_cache.h" @@ -738,12 +738,13 @@ primary_cache_is_2way: case MIPS_R5000: #endif case MIPS_RM5200: + mips_sdcache_write_through = 1; mips_cache_ops.mco_sdcache_wbinv_all = r5k_sdcache_wbinv_all; mips_cache_ops.mco_sdcache_wbinv_range = r5k_sdcache_wbinv_range; mips_cache_ops.mco_sdcache_wbinv_range_index = - r5k_sdcache_wbinv_rangeall; /* XXX? */ + r5k_sdcache_wbinv_range_index; mips_cache_ops.mco_sdcache_inv_range = r5k_sdcache_wbinv_range; mips_cache_ops.mco_sdcache_wb_range = diff --git a/sys/arch/mips/mips/cache_r5k.c b/sys/arch/mips/mips/cache_r5k.c index 3e8906f4099d..3f5c8ff3ab86 100644 --- a/sys/arch/mips/mips/cache_r5k.c +++ b/sys/arch/mips/mips/cache_r5k.c @@ -1,4 +1,4 @@ -/* $NetBSD: cache_r5k.c,v 1.9 2003/07/15 02:43:37 lukem Exp $ */ +/* $NetBSD: cache_r5k.c,v 1.10 2004/12/13 08:39:21 sekiya Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -36,7 +36,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: cache_r5k.c,v 1.9 2003/07/15 02:43:37 lukem Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cache_r5k.c,v 1.10 2004/12/13 08:39:21 sekiya Exp $"); #include @@ -603,20 +603,22 @@ __asm(".set mips3"); void r5k_sdcache_wbinv_all(void) { - vaddr_t va = MIPS_PHYS_TO_KSEG0(0); - vaddr_t eva = va + mips_sdcache_size; - while (va < eva) { - cache_op_r4k_line(va, R5K_Page_Invalidate_S); - va += (128 * 32); - } + r5k_sdcache_wbinv_range(MIPS_PHYS_TO_KSEG0(0), mips_sdcache_size); } -/* XXX: want wbinv_range_index here instead? */ void -r5k_sdcache_wbinv_rangeall(vaddr_t va, vsize_t size) +r5k_sdcache_wbinv_range_index(vaddr_t va, vsize_t size) { - r5k_sdcache_wbinv_all(); + + /* + * 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 & (mips_sdcache_size - 1)); + r5k_sdcache_wbinv_range(va, size); } #define round_page(x) (((x) + (128 * 32 - 1)) & ~(128 * 32 - 1)) @@ -625,13 +627,30 @@ r5k_sdcache_wbinv_rangeall(vaddr_t va, vsize_t size) void r5k_sdcache_wbinv_range(vaddr_t va, vsize_t size) { + uint32_t ostatus, taglo; vaddr_t eva = round_page(va + size); + va = trunc_page(va); + __asm __volatile( + ".set noreorder \n\t" + ".set noat \n\t" + "mfc0 %0, $12 \n\t" + "mtc0 $0, $12 \n\t" + ".set reorder \n\t" + ".set at" + : "=r"(ostatus)); + + __asm __volatile("mfc0 %0, $28" : "=r"(taglo)); + __asm __volatile("mtc0 $0, $28"); + while (va < eva) { cache_op_r4k_line(va, R5K_Page_Invalidate_S); va += (128 * 32); } + + __asm __volatile("mtc0 %0, $12; nop" :: "r"(ostatus)); + __asm __volatile("mtc0 %0, $28; nop" :: "r"(taglo)); } void