Module Name: src Committed By: matt Date: Fri Dec 23 22:47:26 UTC 2011
Modified Files: src/sys/arch/mips/mips [matt-nb5-mips64]: cache.c Log Message: Add code to deal SDcache settings in CFG2. Add support for CFG7 handling for MTI cores. Cleanup cache alias handling. To generate a diff of this commit: cvs rdiff -u -r1.33.96.7 -r1.33.96.8 src/sys/arch/mips/mips/cache.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.7 src/sys/arch/mips/mips/cache.c:1.33.96.8 --- src/sys/arch/mips/mips/cache.c:1.33.96.7 Fri Nov 4 07:43:37 2011 +++ src/sys/arch/mips/mips/cache.c Fri Dec 23 22:47:26 2011 @@ -374,9 +374,10 @@ mips_config_cache_prehistoric(void) mips3_get_cache_config(csizebase); - if (mci->mci_picache_size > PAGE_SIZE || - mci->mci_pdcache_size > PAGE_SIZE) - /* no VCE support if there is no L2 cache */ + /* 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) mci->mci_cache_virtual_alias = true; switch (mci->mci_picache_line_size) { @@ -452,8 +453,9 @@ primary_cache_is_2way: mips3_get_cache_config(csizebase); - if ((mci->mci_picache_size / mci->mci_picache_ways) > PAGE_SIZE || - (mci->mci_pdcache_size / mci->mci_pdcache_ways) > PAGE_SIZE) + 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; switch (mci->mci_picache_line_size) { @@ -582,11 +584,17 @@ primary_cache_is_2way: KASSERT(mci->mci_picache_ways != 0); 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 (mci->mci_icache_virtual_alias) + mci->mci_icache_alias_mask = + mci->mci_picache_way_mask & -PAGE_SIZE; } 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_mask = mci->mci_pdcache_way_size - 1; + if (mci->mci_cache_virtual_alias) + mci->mci_cache_alias_mask = + mci->mci_picache_way_mask & -PAGE_SIZE; } mips_dcache_compute_align(); @@ -621,7 +629,8 @@ 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_cache_virtual_alias = 0; + mci->mci_icache_virtual_alias = false; + mci->mci_cache_virtual_alias = false; /* FALLTHROUGH */ case MIPS_R4600: #ifdef ENABLE_MIPS_R4700 @@ -825,8 +834,10 @@ mips3_get_cache_config(int csizebase) mci->mci_pdcache_line_size = MIPS3_CONFIG_CACHE_L1_LSIZE(config, MIPS3_CONFIG_DB); + mci->mci_icache_alias_mask = + (mci->mci_picache_size / mci->mci_picache_ways - 1) & -PAGE_SHIFT; mci->mci_cache_alias_mask = - ((mci->mci_pdcache_size / mci->mci_pdcache_ways) - 1) & ~PAGE_MASK; + (mci->mci_pdcache_size / mci->mci_pdcache_ways - 1) & -PAGE_SHIFT; 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; @@ -895,6 +906,7 @@ 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; @@ -966,29 +978,29 @@ mips_config_cache_modern(uint32_t cpu_id #define CACHE_DEBUG #ifdef CACHE_DEBUG - 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); + 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: no Icache\n"); else { - printf("MIPS32/64 params: Icache: line = %d, total = %d, " - "ways = %d\n", mci->mci_picache_line_size, + printf("MIPS32/64 params: %s: line=%d, total=%d, " + "ways=%d, sets=%d, colors=%d\n", "Icache", + mci->mci_picache_line_size, mci->mci_picache_way_size * mci->mci_picache_ways, - 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); + mci->mci_picache_ways, + mci->mci_picache_way_size / mci->mci_picache_line_size, + mci->mci_picache_way_size >> PAGE_SHIFT); } if (mci->mci_pdcache_line_size == 0) printf("MIPS32/64 params: no Dcache\n"); else { - printf("MIPS32/64 params: Dcache: line = %d, total = %d, " - "ways = %d\n", mci->mci_pdcache_line_size, + printf("MIPS32/64 params: %s: line=%d, total=%d, " + "ways=%d, sets=%d, colors=%d\n", "Dcache", + mci->mci_pdcache_line_size, mci->mci_pdcache_way_size * mci->mci_pdcache_ways, - 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); + mci->mci_pdcache_ways, + mci->mci_pdcache_way_size / mci->mci_pdcache_line_size, + mci->mci_pdcache_way_size >> PAGE_SHIFT); } #endif /* CACHE_DEBUG */ @@ -1074,6 +1086,88 @@ mips_config_cache_modern(uint32_t cpu_id panic("no Dcache ops for %d byte lines", mci->mci_pdcache_line_size); } + 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; + } + +#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. + */ +#if (MIPS32 + MIPS64 + MIPS32R2 + MIPS64R2) != 0 + mci->mci_cache_alias_mask = mci->mci_pdcache_way_mask & -PAGE_SIZE; + mci->mci_cache_virtual_alias = (mci->mci_cache_alias_mask != 0); +#endif + +#if (MIPS32 + MIPS64 + MIPS32R2 + MIPS64R2 + MIPS64R2_RMIXL) != 0 + mci->mci_icache_alias_mask = mci->mci_picache_way_mask & -PAGE_SIZE; + mci->mci_icache_virtual_alias = (mci->mci_icache_alias_mask != 0); +#endif /* * RMI (NetLogic/Broadcom) don't support WB (op 6) so we have make @@ -1083,11 +1177,43 @@ 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; + 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 + || mci->mci_icache_virtual_alias); + } else { + KASSERT(mci->mci_icache_virtual_alias == 0); + KASSERT(mci->mci_icache_virtual_alias == 0); + } +#if (MIPS32 + MIPS32R2 + MIPS64 + MIPS64R2) > 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; + } + } else { + KASSERT(mci->mci_pdcache_way_size <= PAGE_SIZE); + KASSERT(mci->mci_picache_way_size <= PAGE_SIZE); + } +#endif } mipsNN_cache_init(cfg, cfg1); - if (mips_options.mips_cpu_flags & + if (opts->mips_cpu_flags & (CPU_MIPS_D_CACHE_COHERENT | CPU_MIPS_I_D_CACHE_COHERENT)) { #ifdef CACHE_DEBUG printf(" Dcache is coherent\n"); @@ -1101,8 +1227,18 @@ mips_config_cache_modern(uint32_t cpu_id (void (*)(vaddr_t, vsize_t))cache_noop; mco->mco_pdcache_wb_range = (void (*)(vaddr_t, vsize_t))cache_noop; + + mco->mco_sdcache_wbinv_all = cache_noop; + mco->mco_sdcache_wbinv_range = + (void (*)(vaddr_t, vsize_t))cache_noop; + mco->mco_sdcache_wbinv_range_index = + (void (*)(vaddr_t, vsize_t))cache_noop; + mco->mco_sdcache_inv_range = + (void (*)(vaddr_t, vsize_t))cache_noop; + mco->mco_sdcache_wb_range = + (void (*)(vaddr_t, vsize_t))cache_noop; } - if (mips_options.mips_cpu_flags & CPU_MIPS_I_D_CACHE_COHERENT) { + if (opts->mips_cpu_flags & CPU_MIPS_I_D_CACHE_COHERENT) { #ifdef CACHE_DEBUG printf(" Icache is coherent against Dcache\n"); #endif