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

Reply via email to