Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/arch/mips/mips/cache.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/arch/mips/mips/cache.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.48.26.4 retrieving revision 1.49 diff -u -p -r1.48.26.4 -r1.49 --- src/sys/arch/mips/mips/cache.c 2017/08/28 17:51:45 1.48.26.4 +++ src/sys/arch/mips/mips/cache.c 2015/04/29 08:32:00 1.49 @@ -1,4 +1,4 @@ -/* $NetBSD: cache.c,v 1.48.26.4 2017/08/28 17:51:45 skrll Exp $ */ +/* $NetBSD: cache.c,v 1.49 2015/04/29 08:32:00 hikaru Exp $ */ /* * Copyright 2001, 2002 Wasabi Systems, Inc. @@ -68,7 +68,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.48.26.4 2017/08/28 17:51:45 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cache.c,v 1.49 2015/04/29 08:32:00 hikaru Exp $"); #include "opt_cputype.h" #include "opt_mips_cache.h" @@ -103,6 +103,9 @@ __KERNEL_RCSID(0, "$NetBSD: cache.c,v 1. #endif #endif +struct mips_cache_info mips_cache_info; +struct mips_cache_ops mips_cache_ops; + #ifdef MIPS1 #ifdef ENABLE_MIPS_TX3900 #include @@ -127,32 +130,16 @@ static void mips_config_cache_emips(void static void mips_config_cache_modern(uint32_t); #endif -#if (MIPS1 + MIPS3 + MIPS4 + MIPS32 + MIPS64 + MIPS32R2 + MIPS64R2) > 0 +#if defined(MIPS1) || defined(MIPS3) || defined(MIPS4) /* no-cache definition */ static void no_cache_op(void); -static void no_cache_op_range(register_t va, vsize_t size); -static void no_cache_op_range_index(vaddr_t va, vsize_t size); +static void no_cache_op_range(vaddr_t va, vsize_t size); /* no-cache implementation */ static void no_cache_op(void) {} -static void no_cache_op_range(register_t va, vsize_t size) {} -static void no_cache_op_range_index(vaddr_t va, vsize_t size) {} +static void no_cache_op_range(vaddr_t va, vsize_t size) {} #endif -struct mips_cache_info mips_cache_info; -struct mips_cache_ops mips_cache_ops = { - .mco_intern_icache_sync_range_index = no_cache_op_range_index, - .mco_intern_icache_sync_range = no_cache_op_range, - .mco_intern_pdcache_sync_all= no_cache_op, - .mco_intern_pdcache_sync_range_index = no_cache_op_range_index, - .mco_intern_pdcache_sync_range = no_cache_op_range, - .mco_intern_pdcache_wbinv_range_index = no_cache_op_range_index, - .mco_intern_sdcache_sync_all= no_cache_op, - .mco_intern_sdcache_sync_range_index = no_cache_op_range_index, - .mco_intern_sdcache_sync_range = no_cache_op_range, - .mco_intern_sdcache_wbinv_range_index = no_cache_op_range_index, -}; - /* * mips_dcache_compute_align: * @@ -191,7 +178,7 @@ mips_config_cache(void) struct mips_cache_ops * const mco = &mips_cache_ops; #endif const mips_prid_t cpu_id = mips_options.mips_cpu_id; - + #if defined(MIPS1) || defined(MIPS3) || defined(MIPS4) if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_PREHISTORIC) mips_config_cache_prehistoric(); @@ -279,14 +266,14 @@ mips_config_cache_prehistoric(void) mco->mco_icache_sync_range = r3k_icache_sync_range; mco->mco_icache_sync_range_index = - (void (*)(vaddr_t, vsize_t)) mco->mco_icache_sync_range; + mco->mco_icache_sync_range; mco->mco_pdcache_wbinv_all = r3k_pdcache_wbinv_all; mco->mco_pdcache_wbinv_range = r3k_pdcache_inv_range; mco->mco_pdcache_wbinv_range_index = - (void (*)(vaddr_t, vsize_t)) mco->mco_pdcache_wbinv_range; + mco->mco_pdcache_wbinv_range; mco->mco_pdcache_inv_range = r3k_pdcache_inv_range; mco->mco_pdcache_wb_range = @@ -312,16 +299,14 @@ mips_config_cache_prehistoric(void) mco->mco_icache_sync_range = tx3900_icache_sync_range_16; mco->mco_icache_sync_range_index = - (void (*)(vaddr_t, vsize_t)) - tx3900_icache_sync_range_16; + tx3900_icache_sync_range_16; mco->mco_pdcache_wbinv_all = tx3900_pdcache_wbinv_all_4; mco->mco_pdcache_wbinv_range = tx3900_pdcache_inv_range_4; mco->mco_pdcache_wbinv_range_index = - (void (*)(vaddr_t, vsize_t)) - tx3900_pdcache_inv_range_4; + tx3900_pdcache_inv_range_4; mco->mco_pdcache_inv_range = tx3900_pdcache_inv_range_4; mco->mco_pdcache_wb_range = @@ -344,8 +329,7 @@ mips_config_cache_prehistoric(void) tx3920_icache_sync_range_16wt : tx3920_icache_sync_range_16wb; mco->mco_icache_sync_range_index = - (void (*)(vaddr_t, vsize_t)) - mco->mco_icache_sync_range; + mco->mco_icache_sync_range; mco->mco_pdcache_wbinv_all = mci->mci_pdcache_write_through ? @@ -356,8 +340,7 @@ mips_config_cache_prehistoric(void) tx3920_pdcache_inv_range_16 : tx3920_pdcache_wbinv_range_16wb; mco->mco_pdcache_wbinv_range_index = - (void (*)(vaddr_t, vsize_t)) - mco->mco_pdcache_wbinv_range; + mco->mco_pdcache_wbinv_range; mco->mco_pdcache_inv_range = tx3920_pdcache_inv_range_16; mco->mco_pdcache_wb_range = @@ -410,26 +393,28 @@ mips_config_cache_prehistoric(void) mips3_get_cache_config(csizebase); - /* no VCE support if there is no L2 cache */ - if (mci->mci_picache_size > PAGE_SIZE) - mci->mci_icache_virtual_alias = true; - if (mci->mci_pdcache_size > PAGE_SIZE) + if (mci->mci_picache_size > PAGE_SIZE || + mci->mci_pdcache_size > PAGE_SIZE) + /* no VCE support if there is no L2 cache */ mci->mci_cache_virtual_alias = true; - mco->mco_icache_sync_all = r4k_icache_sync_all_generic; switch (mci->mci_picache_line_size) { case 16: + mco->mco_icache_sync_all = + r4k_icache_sync_all_16; mco->mco_icache_sync_range = - cache_r4k_icache_hit_inv_16; + r4k_icache_sync_range_16; mco->mco_icache_sync_range_index = - cache_r4k_icache_index_inv_16; + r4k_icache_sync_range_index_16; break; case 32: + mco->mco_icache_sync_all = + r4k_icache_sync_all_32; mco->mco_icache_sync_range = - cache_r4k_icache_hit_inv_32; + r4k_icache_sync_range_32; mco->mco_icache_sync_range_index = - cache_r4k_icache_index_inv_32; + r4k_icache_sync_range_index_32; break; default: @@ -437,34 +422,39 @@ mips_config_cache_prehistoric(void) mci->mci_picache_line_size); } - mco->mco_pdcache_wbinv_all = r4k_pdcache_wbinv_all_generic; switch (mci->mci_pdcache_line_size) { case 16: + mco->mco_pdcache_wbinv_all = + r4k_pdcache_wbinv_all_16; mco->mco_pdcache_wbinv_range = - cache_r4k_pdcache_hit_wb_inv_16; + r4k_pdcache_wbinv_range_16; mco->mco_pdcache_wbinv_range_index = - cache_r4k_pdcache_index_wb_inv_16; + r4k_pdcache_wbinv_range_index_16; mco->mco_pdcache_inv_range = - cache_r4k_pdcache_hit_inv_16; + r4k_pdcache_inv_range_16; mco->mco_pdcache_wb_range = - cache_r4k_pdcache_hit_wb_16; + r4k_pdcache_wb_range_16; break; case 32: + mco->mco_pdcache_wbinv_all = + r4k_pdcache_wbinv_all_32; mco->mco_pdcache_wbinv_range = - cache_r4k_pdcache_hit_wb_inv_32; + r4k_pdcache_wbinv_range_32; mco->mco_pdcache_wbinv_range_index = - cache_r4k_pdcache_index_wb_inv_32; + r4k_pdcache_wbinv_range_index_32; mco->mco_pdcache_inv_range = - cache_r4k_pdcache_hit_inv_32; + r4k_pdcache_inv_range_32; mco->mco_pdcache_wb_range = - cache_r4k_pdcache_hit_wb_32; + r4k_pdcache_wb_range_32; break; default: panic("r4k pdcache line size %d", mci->mci_pdcache_line_size); } + + /* Virtually-indexed cache; no use for colors. */ break; case MIPS_R4600: @@ -481,60 +471,50 @@ primary_cache_is_2way: mips3_get_cache_config(csizebase); - if (mci->mci_picache_size / mci->mci_picache_ways > PAGE_SIZE) - mci->mci_icache_virtual_alias = true; - if (mci->mci_pdcache_size / mci->mci_pdcache_ways > PAGE_SIZE) + if ((mci->mci_picache_size / mci->mci_picache_ways) > PAGE_SIZE || + (mci->mci_pdcache_size / mci->mci_pdcache_ways) > PAGE_SIZE) mci->mci_cache_virtual_alias = true; - mco->mco_icache_sync_all = r5k_picache_sync_all; - mco->mco_icache_sync_range = r5k_picache_sync_range; - mco->mco_icache_sync_range_index = r5k_picache_sync_range_index; - switch (mci->mci_picache_line_size) { case 32: - /* 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; + mco->mco_icache_sync_all = + r5k_icache_sync_all_32; + mco->mco_icache_sync_range = + r5k_icache_sync_range_32; + mco->mco_icache_sync_range_index = + r5k_icache_sync_range_index_32; break; default: - panic("r5k picache line size %u", + panic("r5k picache line size %d", mci->mci_picache_line_size); } - mco->mco_pdcache_wbinv_all = r5k_pdcache_wbinv_all; - mco->mco_pdcache_wbinv_range_index = - r5k_pdcache_wbinv_range_index; - switch (mci->mci_pdcache_line_size) { case 16: + mco->mco_pdcache_wbinv_all = + r5k_pdcache_wbinv_all_16; mco->mco_pdcache_wbinv_range = - cache_r4k_pdcache_hit_wb_inv_16; + r5k_pdcache_wbinv_range_16; + mco->mco_pdcache_wbinv_range_index = + r5k_pdcache_wbinv_range_index_16; mco->mco_pdcache_inv_range = - cache_r4k_pdcache_hit_inv_16; + r5k_pdcache_inv_range_16; mco->mco_pdcache_wb_range = - cache_r4k_pdcache_hit_wb_16; - - /* used internally by r5k_pdcache_wbinv_range_index */ - mco->mco_intern_pdcache_wbinv_range_index = - cache_r4k_pdcache_index_wb_inv_16; + r5k_pdcache_wb_range_16; break; case 32: + mco->mco_pdcache_wbinv_all = + r5k_pdcache_wbinv_all_32; mco->mco_pdcache_wbinv_range = - cache_r4k_pdcache_hit_wb_inv_32; + r5k_pdcache_wbinv_range_32; + mco->mco_pdcache_wbinv_range_index = + r5k_pdcache_wbinv_range_index_32; mco->mco_pdcache_inv_range = - cache_r4k_pdcache_hit_inv_32; + r5k_pdcache_inv_range_32; mco->mco_pdcache_wb_range = - cache_r4k_pdcache_hit_wb_32; - - /* used internally by r5k_pdcache_wbinv_range_index */ - mco->mco_intern_pdcache_wbinv_range_index = - cache_r4k_pdcache_index_wb_inv_32; + r5k_pdcache_wb_range_32; break; default: @@ -542,11 +522,6 @@ primary_cache_is_2way: mci->mci_pdcache_line_size); } - 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; - /* * Deal with R4600 chip bugs. */ @@ -579,6 +554,8 @@ primary_cache_is_2way: mco->mco_pdcache_wbinv_range = vr4131v1_pdcache_wbinv_range_16; } + + /* Virtually-indexed cache; no use for colors. */ break; #ifdef ENABLE_MIPS4_CACHE_R10K case MIPS_R10000: @@ -619,10 +596,9 @@ primary_cache_is_2way: mci->mci_sdcache_line_size = 32; /* don't trust config reg */ - if (mci->mci_picache_size / mci->mci_picache_ways > PAGE_SIZE) - mci->mci_icache_virtual_alias = true; - if (mci->mci_pdcache_size / mci->mci_pdcache_ways > PAGE_SIZE) - mci->mci_cache_virtual_alias = true; + if (mci->mci_picache_size / mci->mci_picache_ways > PAGE_SIZE || + mci->mci_pdcache_size / mci->mci_pdcache_ways > PAGE_SIZE) + mci->mci_cache_virtual_alias = 1; mco->mco_icache_sync_all = ls2_icache_sync_all; @@ -660,33 +636,15 @@ primary_cache_is_2way: */ if (mci->mci_picache_size) { KASSERT(mci->mci_picache_ways != 0); - mci->mci_picache_way_size = mci->mci_picache_size / mci->mci_picache_ways; + mci->mci_picache_way_size = (mci->mci_picache_size / mci->mci_picache_ways); mci->mci_picache_way_mask = mci->mci_picache_way_size - 1; -#if (MIPS2 + MIPS3 + MIPS4) > 0 - if (mci->mci_icache_virtual_alias) - mci->mci_icache_alias_mask = - mci->mci_picache_way_mask & -PAGE_SIZE; -#endif } if (mci->mci_pdcache_size) { KASSERT(mci->mci_pdcache_ways != 0); - mci->mci_pdcache_way_size = mci->mci_pdcache_size / mci->mci_pdcache_ways; + mci->mci_pdcache_way_size = (mci->mci_pdcache_size / mci->mci_pdcache_ways); mci->mci_pdcache_way_mask = mci->mci_pdcache_way_size - 1; -#if (MIPS2 + MIPS3 + MIPS4) > 0 - if (mci->mci_cache_virtual_alias) - mci->mci_cache_alias_mask = - mci->mci_pdcache_way_mask & -PAGE_SIZE; -#endif } -#if (MIPS2 + MIPS3 + MIPS4) > 0 - if (mci->mci_cache_virtual_alias) { - mci->mci_cache_prefer_mask = mci->mci_pdcache_way_mask; - - uvmexp.ncolors = (mci->mci_cache_prefer_mask >> PAGE_SHIFT) + 1; - } -#endif - mips_dcache_compute_align(); if (mci->mci_sdcache_line_size == 0) @@ -719,8 +677,7 @@ primary_cache_is_2way: (MIPS3_MAX_PCACHE_SIZE - 1) & ~PAGE_MASK; /* va[14:12] */ mci->mci_cache_prefer_mask = MIPS3_MAX_PCACHE_SIZE - 1; - mci->mci_icache_virtual_alias = false; - mci->mci_cache_virtual_alias = false; + mci->mci_cache_virtual_alias = 0; /* FALLTHROUGH */ case MIPS_R4600: #ifdef ENABLE_MIPS_R4700 @@ -728,51 +685,45 @@ primary_cache_is_2way: #endif switch (mci->mci_sdcache_ways) { case 1: - mco->mco_sdcache_wbinv_all = - r4k_sdcache_wbinv_all_generic; switch (mci->mci_sdcache_line_size) { - case 16: - mco->mco_sdcache_wbinv_range = - cache_r4k_sdcache_hit_wb_inv_16; - mco->mco_sdcache_wbinv_range_index = - cache_r4k_sdcache_index_wb_inv_16; - mco->mco_sdcache_inv_range = - cache_r4k_sdcache_hit_inv_16; - mco->mco_sdcache_wb_range = - cache_r4k_sdcache_hit_wb_16; - break; - case 32: + mco->mco_sdcache_wbinv_all = + r4k_sdcache_wbinv_all_32; mco->mco_sdcache_wbinv_range = - cache_r4k_sdcache_hit_wb_inv_32; + r4k_sdcache_wbinv_range_32; mco->mco_sdcache_wbinv_range_index = - cache_r4k_sdcache_index_wb_inv_32; + r4k_sdcache_wbinv_range_index_32; mco->mco_sdcache_inv_range = - cache_r4k_sdcache_hit_inv_32; + r4k_sdcache_inv_range_32; mco->mco_sdcache_wb_range = - cache_r4k_sdcache_hit_wb_32; + r4k_sdcache_wb_range_32; break; + case 16: case 64: + mco->mco_sdcache_wbinv_all = + r4k_sdcache_wbinv_all_generic; mco->mco_sdcache_wbinv_range = - cache_r4k_sdcache_hit_wb_inv_64; + r4k_sdcache_wbinv_range_generic; mco->mco_sdcache_wbinv_range_index = - cache_r4k_sdcache_index_wb_inv_64; + r4k_sdcache_wbinv_range_index_generic; mco->mco_sdcache_inv_range = - cache_r4k_sdcache_hit_inv_64; + r4k_sdcache_inv_range_generic; mco->mco_sdcache_wb_range = - cache_r4k_sdcache_hit_wb_64; + r4k_sdcache_wb_range_generic; break; case 128: + mco->mco_sdcache_wbinv_all = + r4k_sdcache_wbinv_all_128; mco->mco_sdcache_wbinv_range = - cache_r4k_sdcache_hit_wb_inv_128; + r4k_sdcache_wbinv_range_128; mco->mco_sdcache_wbinv_range_index = - cache_r4k_sdcache_index_wb_inv_128; + r4k_sdcache_wbinv_range_index_128; mco->mco_sdcache_inv_range = - cache_r4k_sdcache_hit_inv_128; + r4k_sdcache_inv_range_128; mco->mco_sdcache_wb_range = - cache_r4k_sdcache_hit_wb_128; + r4k_sdcache_wb_range_128; break; default: @@ -799,7 +750,8 @@ primary_cache_is_2way: r5k_sdcache_wbinv_range_index; mco->mco_sdcache_inv_range = r5k_sdcache_wbinv_range; - mco->mco_sdcache_wb_range = no_cache_op_range; + mco->mco_sdcache_wb_range = + r5k_sdcache_wb_range; break; #ifdef ENABLE_MIPS4_CACHE_R10K case MIPS_R10000: @@ -851,7 +803,7 @@ primary_cache_is_2way: */ if (mci->mci_sdcache_size) { KASSERT(mci->mci_sdcache_ways != 0); - mci->mci_sdcache_way_size = mci->mci_sdcache_size / mci->mci_sdcache_ways; + mci->mci_sdcache_way_size = (mci->mci_sdcache_size / mci->mci_sdcache_ways); mci->mci_sdcache_way_mask = mci->mci_sdcache_way_size - 1; } @@ -881,15 +833,16 @@ mips_config_cache_emips(void) mci->mci_picache_ways = 1; mci->mci_pdcache_ways = 1; - mci->mci_pdcache_write_through = true; + mci->mci_pdcache_write_through = 1; mco->mco_icache_sync_all = no_cache_op; mco->mco_icache_sync_range = no_cache_op_range; - mco->mco_icache_sync_range_index = no_cache_op_range_index; + mco->mco_icache_sync_range_index = mco->mco_icache_sync_range; mco->mco_pdcache_wbinv_all = no_cache_op; mco->mco_pdcache_wbinv_range = no_cache_op_range; - mco->mco_pdcache_wbinv_range_index = no_cache_op_range_index; + mco->mco_pdcache_wbinv_range_index = + mco->mco_pdcache_wbinv_range; mco->mco_pdcache_inv_range = no_cache_op_range; mco->mco_pdcache_wb_range = no_cache_op_range; @@ -995,6 +948,12 @@ mips3_get_cache_config(int csizebase) mci->mci_pdcache_line_size = MIPS3_CONFIG_CACHE_L1_LSIZE(config, MIPS3_CONFIG_DB); + mci->mci_cache_alias_mask = + ((mci->mci_pdcache_size / mci->mci_pdcache_ways) - 1) & ~PAGE_MASK; + mci->mci_cache_prefer_mask = + max(mci->mci_pdcache_size, mci->mci_picache_size) - 1; + uvmexp.ncolors = (mci->mci_cache_alias_mask >> PAGE_SHIFT) + 1; + switch(MIPS_PRID_IMPL(cpu_id)) { #ifndef ENABLE_MIPS_R3NKK case MIPS_R5000: @@ -1004,7 +963,7 @@ mips3_get_cache_config(int csizebase) break; } - /* + /* * If CPU has a software-enabled L2 cache, check both if it's * present and if it's enabled before making assumptions the * L2 is usable. If the L2 is disabled, we treat it the same @@ -1013,7 +972,7 @@ mips3_get_cache_config(int csizebase) if ((config & MIPS3_CONFIG_SC) == 0) { if (has_sdcache_enable == 0 || (has_sdcache_enable && (config & MIPS3_CONFIG_SE))) { - mci->mci_sdcache_line_size = + mci->mci_sdcache_line_size = MIPS3_CONFIG_CACHE_L2_LSIZE(config); if ((config & MIPS3_CONFIG_SS) == 0) mci->mci_scache_unified = true; @@ -1051,12 +1010,14 @@ mips4_get_cache_config(int csizebase) #if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 0 +static void cache_noop(void) __unused; +static void cache_noop(void) {} + static void mips_config_cache_modern(uint32_t cpu_id) { struct mips_cache_info * const mci = &mips_cache_info; struct mips_cache_ops * const mco = &mips_cache_ops; - struct mips_options * const opts = &mips_options; /* MIPS32/MIPS64, use coprocessor 0 config registers */ uint32_t cfg, cfg1; @@ -1076,7 +1037,6 @@ mips_config_cache_modern(uint32_t cpu_id mci->mci_pdcache_line_size = 128; mci->mci_pdcache_way_size = 256; mci->mci_pdcache_ways = 64; - mci->mci_pdcache_write_through = true; mci->mci_pdcache_size = mci->mci_pdcache_way_size * mci->mci_pdcache_ways; @@ -1105,7 +1065,7 @@ mips_config_cache_modern(uint32_t cpu_id mci->mci_pdcache_size = mci->mci_pdcache_way_size * mci->mci_pdcache_ways; mci->mci_pdcache_way_mask = mci->mci_pdcache_way_size - 1; - uvmexp.ncolors = atop(mci->mci_pdcache_way_size); + uvmexp.ncolors = atop(mci->mci_pdcache_size) / mci->mci_pdcache_ways; break; } @@ -1127,13 +1087,8 @@ mips_config_cache_modern(uint32_t cpu_id mci->mci_picache_ways = MIPSNN_CFG1_IA(cfg1) + 1; /* - * Is this Icache virtually indexed and virtually tagged? - */ - mci->mci_picache_vivt = (cfg & MIPSNN_CFG_VI) != 0; - - /* * Compute the total size and "way mask" for the - * primary Icache. + * primary Dcache. */ mci->mci_picache_size = mci->mci_picache_way_size * mci->mci_picache_ways; @@ -1143,250 +1098,139 @@ mips_config_cache_modern(uint32_t cpu_id #define CACHE_DEBUG #ifdef CACHE_DEBUG - printf("MIPS32/64 params: cpu arch: %d\n", opts->mips_cpu_arch); - printf("MIPS32/64 params: TLB entries: %d\n", opts->mips_num_tlb_entries); - if (mci->mci_picache_line_size == 0) { + printf("MIPS32/64 params: cpu arch: %d\n", mips_options.mips_cpu_arch); + printf("MIPS32/64 params: TLB entries: %d\n", mips_options.mips_num_tlb_entries); + if (mci->mci_picache_line_size == 0) printf("MIPS32/64 params: no Icache\n"); - } else { - printf("MIPS32/64 params: %s: line=%d, total=%d, " - "ways=%d, sets=%d, colors=%d\n", "Icache", - mci->mci_picache_line_size, + else { + printf("MIPS32/64 params: Icache: line = %d, total = %d, " + "ways = %d\n", mci->mci_picache_line_size, mci->mci_picache_way_size * mci->mci_picache_ways, - mci->mci_picache_ways, - mci->mci_picache_way_size / mci->mci_picache_line_size, - mci->mci_picache_way_size >> PAGE_SHIFT); + mci->mci_picache_ways); + printf("\t\t sets = %d\n", (mci->mci_picache_way_size * + mci->mci_picache_ways / mci->mci_picache_line_size) / + mci->mci_picache_ways); } - if (mci->mci_pdcache_line_size == 0) { + if (mci->mci_pdcache_line_size == 0) printf("MIPS32/64 params: no Dcache\n"); - } else { - printf("MIPS32/64 params: %s: line=%d, total=%d, " - "ways=%d, sets=%d, colors=%d\n", "Dcache", - mci->mci_pdcache_line_size, + else { + printf("MIPS32/64 params: Dcache: line = %d, total = %d, " + "ways = %d\n", mci->mci_pdcache_line_size, mci->mci_pdcache_way_size * mci->mci_pdcache_ways, - mci->mci_pdcache_ways, - mci->mci_pdcache_way_size / mci->mci_pdcache_line_size, - mci->mci_pdcache_way_size >> PAGE_SHIFT); + mci->mci_pdcache_ways); + printf("\t\t sets = %d\n", (mci->mci_pdcache_way_size * + mci->mci_pdcache_ways / mci->mci_pdcache_line_size) / + mci->mci_pdcache_ways); } #endif /* CACHE_DEBUG */ - 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_picache_line_size) { case 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; + 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; break; case 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; + 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; break; #ifdef MIPS_DISABLE_L1_CACHE case 0: - mco->mco_icache_sync_all = no_cache_op; - mco->mco_icache_sync_range = no_cache_op_range; - mco->mco_icache_sync_range_index = no_cache_op_range_index; + mco->mco_icache_sync_all = cache_noop; + mco->mco_icache_sync_range = + (void (*)(vaddr_t, vsize_t))cache_noop; + mco->mco_icache_sync_range_index = + (void (*)(vaddr_t, vsize_t))cache_noop; break; #endif - case 64: - /* used internally by mipsNN_picache_sync_range */ - mco->mco_intern_icache_sync_range = - cache_r4k_icache_hit_inv_64; - - /* used internally by mipsNN_picache_sync_range_index */ - mco->mco_intern_icache_sync_range_index = - cache_r4k_icache_index_inv_64; - break; - case 128: #ifdef MIPS64_OCTEON + case 128: mco->mco_icache_sync_all = octeon_icache_sync_all; mco->mco_icache_sync_range = octeon_icache_sync_range; mco->mco_icache_sync_range_index = octeon_icache_sync_range_index; -#else - /* used internally by mipsNN_picache_sync_range */ - mco->mco_intern_icache_sync_range = - cache_r4k_icache_hit_inv_128; - - /* used internally by mipsNN_picache_sync_range_index */ - mco->mco_intern_icache_sync_range_index = - cache_r4k_icache_index_inv_128; -#endif break; +#endif default: - panic("no Icache ops for %dB lines", + panic("no Icache ops for %d byte lines", mci->mci_picache_line_size); } - mco->mco_pdcache_wbinv_all = mipsNN_pdcache_wbinv_all; - mco->mco_pdcache_wbinv_range_index = mipsNN_pdcache_wbinv_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 = - cache_r4k_pdcache_hit_wb_inv_16; + mipsNN_pdcache_wbinv_range_16; + mco->mco_pdcache_wbinv_range_index = + mco->mco_intern_pdcache_wbinv_range_index = + mipsNN_pdcache_wbinv_range_index_16; mco->mco_pdcache_inv_range = - cache_r4k_pdcache_hit_inv_16; + mipsNN_pdcache_inv_range_16; mco->mco_pdcache_wb_range = - 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; + mco->mco_intern_pdcache_wb_range = + mipsNN_pdcache_wb_range_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 = - cache_r4k_pdcache_hit_wb_inv_32; + mipsNN_pdcache_wbinv_range_32; + mco->mco_pdcache_wbinv_range_index = + mco->mco_intern_pdcache_wbinv_range_index = + mipsNN_pdcache_wbinv_range_index_32; mco->mco_pdcache_inv_range = - cache_r4k_pdcache_hit_inv_32; + mipsNN_pdcache_inv_range_32; mco->mco_pdcache_wb_range = - 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; + mco->mco_intern_pdcache_wb_range = + mipsNN_pdcache_wb_range_32; break; - case 64: - mco->mco_pdcache_wbinv_range = - cache_r4k_pdcache_hit_wb_inv_64; - mco->mco_pdcache_inv_range = - cache_r4k_pdcache_hit_inv_64; - mco->mco_pdcache_wb_range = - cache_r4k_pdcache_hit_wb_64; - - /* used internally by mipsNN_pdcache_wbinv_range_index */ - mco->mco_intern_pdcache_wbinv_range_index = - cache_r4k_pdcache_index_wb_inv_64; - case 128: #ifdef MIPS64_OCTEON - mco->mco_pdcache_wbinv_all = octeon_pdcache_inv_all; - mco->mco_pdcache_wbinv_range = octeon_pdcache_inv_range; - mco->mco_pdcache_wbinv_range_index = octeon_pdcache_inv_range_index; - mco->mco_pdcache_inv_range = octeon_pdcache_inv_range; - mco->mco_pdcache_wb_range = no_cache_op_range; -#else + case 128: + mco->mco_pdcache_wbinv_all = + mco->mco_intern_pdcache_wbinv_all = + octeon_pdcache_inv_all; mco->mco_pdcache_wbinv_range = - cache_r4k_pdcache_hit_wb_inv_128; + octeon_pdcache_inv_range; + mco->mco_pdcache_wbinv_range_index = + mco->mco_intern_pdcache_wbinv_range_index = + octeon_pdcache_inv_range_index; mco->mco_pdcache_inv_range = - cache_r4k_pdcache_hit_inv_128; + (void (*)(vaddr_t, vsize_t))cache_noop; mco->mco_pdcache_wb_range = - cache_r4k_pdcache_hit_wb_128; - - /* used internally by mipsNN_pdcache_wbinv_range_index */ - mco->mco_intern_pdcache_wbinv_range_index = - cache_r4k_pdcache_index_wb_inv_128; -#endif + mco->mco_intern_pdcache_wb_range = + octeon_pdcache_inv_range; break; +#endif #ifdef MIPS_DISABLE_L1_CACHE case 0: - mco->mco_pdcache_wbinv_all = no_cache_op; - mco->mco_pdcache_wbinv_range = no_cache_op_range; - mco->mco_pdcache_wbinv_range_index = no_cache_op_index; - mco->mco_pdcache_inv_range = no_cache_op_range; - mco->mco_pdcache_wb_range = no_cache_op_range; + 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 %dB lines", + panic("no Dcache ops for %d byte lines", mci->mci_pdcache_line_size); } - 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(); - - switch (MIPSNN_GET(CFG2_SL, cfg2)) { - case MIPSNN_CFG2_SL_NONE: - break; - default: - mci->mci_scache_unified = true; - - mci->mci_sdcache_line_size = MIPSNN_CFG2_SL(cfg2); - mci->mci_sdcache_way_size = - mci->mci_sdcache_line_size * MIPSNN_CFG2_SS(cfg2); - mci->mci_sdcache_ways = MIPSNN_CFG2_SA(cfg2) + 1; - - /* - * Compute the total size and "way mask" for the - * secondary Dcache. - */ - mci->mci_sdcache_size = - mci->mci_sdcache_way_size * mci->mci_sdcache_ways; - mci->mci_sdcache_way_mask = - mci->mci_sdcache_way_size - 1; - - /* - * cache is unified so copy data info to inst info. - */ - mci->mci_sicache_line_size = mci->mci_sdcache_line_size; - mci->mci_sicache_way_size = mci->mci_sdcache_way_size; - mci->mci_sicache_ways = mci->mci_sdcache_ways; - mci->mci_sicache_size = mci->mci_sdcache_size; - mci->mci_sicache_way_mask = mci->mci_sdcache_way_mask; - - break; - } - - // Note we don't set up any sd cache ops because we expect that - // the coherence checks below will overwrite them with no ops. - -#ifdef CACHE_DEBUG - if (mci->mci_sdcache_line_size != 0) { - printf("MIPS32/64 params: %s: line=%d, total=%d, " - "ways=%d, sets=%d, colors=%d\n", - "SDcache", - mci->mci_sdcache_line_size, - mci->mci_sdcache_way_size * mci->mci_sdcache_ways, - mci->mci_sdcache_ways, - mci->mci_sdcache_way_size - / mci->mci_sdcache_line_size, - mci->mci_sdcache_way_size >> PAGE_SHIFT); - } -#endif - - switch (MIPSNN_GET(CFG2_TL, cfg2)) { - case MIPSNN_CFG2_TL_NONE: - break; - default: - mci->mci_tcache_line_size = MIPSNN_CFG2_TL(cfg2); - mci->mci_tcache_way_size = - mci->mci_tcache_line_size * MIPSNN_CFG2_TS(cfg2); - mci->mci_tcache_ways = MIPSNN_CFG2_TA(cfg2) + 1; - - /* - * Compute the total size and "way mask" for the - * secondary Dcache. - */ - mci->mci_tcache_size = - mci->mci_tcache_way_size * mci->mci_tcache_ways; - mci->mci_tcache_way_mask = - mci->mci_tcache_way_size - 1; - break; - } - } - - /* - * calculate the alias masks and from them set to virtual alias flags. - */ - mci->mci_cache_alias_mask = mci->mci_pdcache_way_mask & -PAGE_SIZE; - mci->mci_cache_virtual_alias = (mci->mci_cache_alias_mask != 0); - - mci->mci_icache_alias_mask = mci->mci_picache_way_mask & -PAGE_SIZE; - mci->mci_icache_virtual_alias = (mci->mci_icache_alias_mask != 0); - /* * RMI (NetLogic/Broadcom) don't support WB (op 6) so we have to make * do with WBINV (op 5). This is merely for correctness since because @@ -1394,66 +1238,36 @@ 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_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; - KASSERT(PAGE_SIZE >= mci->mci_picache_way_size - || MIPS_ICACHE_VIRTUAL_ALIAS); - } else { - KASSERT(MIPS_CACHE_VIRTUAL_ALIAS == 0); - KASSERT(MIPS_ICACHE_VIRTUAL_ALIAS == 0); - } - } else if (MIPS_PRID_CID(cpu_id) == MIPS_PRID_CID_MTI) { - /* - * All MTI cores share a (mostly) common config7 defintion. - * Use it to determine if the caches have virtual aliases. - * If the core doesn't have a config7 register, its caches - * are too small or have too many ways to have aliases. - */ - if (opts->mips_cpu->cpu_cp0flags & MIPS_CP0FL_CONFIG7) { - const uint32_t cfg7 = mipsNN_cp0_config7_read(); - if (cfg7 & MIPSNN_MTI_CFG7_AR) { - /* [Data] Alias Removal Present */ - mci->mci_cache_virtual_alias = false; - } - if (cfg7 & MIPSNN_MTI_CFG7_IAR) { - /* 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 - } + mco->mco_intern_pdcache_wb_range = mco->mco_pdcache_wbinv_range; } mipsNN_cache_init(cfg, cfg1); - if (opts->mips_cpu_flags & + if (mips_options.mips_cpu_flags & (CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_I_D_CACHE_COHERENT)) { #ifdef CACHE_DEBUG printf(" Dcache is coherent\n"); #endif - mco->mco_pdcache_wbinv_all = no_cache_op; - mco->mco_pdcache_wbinv_range = no_cache_op_range; - mco->mco_pdcache_wbinv_range_index = no_cache_op_range_index; - mco->mco_pdcache_inv_range = no_cache_op_range; - mco->mco_pdcache_wb_range = no_cache_op_range; - mco->mco_sdcache_wbinv_all = no_cache_op; - mco->mco_sdcache_wbinv_range = no_cache_op_range; - mco->mco_sdcache_wbinv_range_index = no_cache_op_range_index; - mco->mco_sdcache_inv_range = no_cache_op_range; - mco->mco_sdcache_wb_range = no_cache_op_range; + mco->mco_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_pdcache_inv_range = + (void (*)(vaddr_t, vsize_t))cache_noop; + mco->mco_pdcache_wb_range = + (void (*)(vaddr_t, vsize_t))cache_noop; } - if (opts->mips_cpu_flags & CPU_MIPS_I_D_CACHE_COHERENT) { + if (mips_options.mips_cpu_flags & CPU_MIPS_I_D_CACHE_COHERENT) { #ifdef CACHE_DEBUG printf(" Icache is coherent against Dcache\n"); #endif - mco->mco_intern_pdcache_sync_all = no_cache_op; - mco->mco_intern_pdcache_sync_range_index = no_cache_op_range_index; - mco->mco_intern_pdcache_sync_range = no_cache_op_range; + mco->mco_intern_pdcache_wbinv_all = + cache_noop; + mco->mco_intern_pdcache_wbinv_range_index = + (void (*)(vaddr_t, vsize_t))cache_noop; + mco->mco_intern_pdcache_wb_range = + (void (*)(vaddr_t, vsize_t))cache_noop; } } #endif /* MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2 > 0 */