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); -}