Module Name:    src
Committed By:   matt
Date:           Fri Sep 11 23:51:26 UTC 2009

Modified Files:
        src/sys/arch/mips/mips [matt-nb5-mips64]: locore.S mips_machdep.c

Log Message:
Add code to probe TLB for VA/PA/PG_MASK sizes
Increase waynames to include 8-way.


To generate a diff of this commit:
cvs rdiff -u -r1.167.38.2 -r1.167.38.3 src/sys/arch/mips/mips/locore.S
cvs rdiff -u -r1.205.4.1.2.1.2.7 -r1.205.4.1.2.1.2.8 \
    src/sys/arch/mips/mips/mips_machdep.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/locore.S
diff -u src/sys/arch/mips/mips/locore.S:1.167.38.2 src/sys/arch/mips/mips/locore.S:1.167.38.3
--- src/sys/arch/mips/mips/locore.S:1.167.38.2	Mon Sep  7 22:05:45 2009
+++ src/sys/arch/mips/mips/locore.S	Fri Sep 11 23:51:25 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.S,v 1.167.38.2 2009/09/07 22:05:45 matt Exp $	*/
+/*	$NetBSD: locore.S,v 1.167.38.3 2009/09/11 23:51:25 matt Exp $	*/
 
 /*
  * Copyright (c) 1992, 1993
@@ -530,6 +530,98 @@
 	nop
 END(mips_cp0_status_write)
 
+#ifdef MIPS3_PLUS
+	.set	push
+	.set	mips3
+/*
+ * uint64_t mips_cp0_tlb_entry_hi_probe(void);
+ *
+ * Write 1s to the VPN field of Entry_Hi0 to see how many VA bits
+ * are implemented.  Assumes that interrupts are disabled.
+ */
+LEAF(mips_cp0_tlb_entry_hi_probe)
+	dmfc0	t0, MIPS_COP_0_TLB_HI
+	li	v0, -4096	/* all 1s except low 12 bits */
+	dsll	v0, v0, 2	/* except the top 2 */
+	dsrl	v0, v0, 2
+	dmtc0	v0, MIPS_COP_0_TLB_HI
+	COP0_SYNC
+	nop
+	nop
+	dmfc0	v0, MIPS_COP_0_TLB_HI
+	dmtc0	t0, MIPS_COP_0_TLB_HI
+	COP0_SYNC
+	nop
+#ifdef __mips_o32
+	nop
+#if BYTE_ORDER == BIG_ENDIAN
+	srl	v1, v0, 0
+	dsra	v0, v0, 32
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+	dsra	v1, v0, 32
+	srl	v0, v0, 0
+#endif
+#endif /* __mips_o32 */
+	j	ra
+	 nop
+END(mips_cp0_tlb_entry_hi_probe)
+
+/*
+ * uint64_t mips_cp0_tlb_entry_lo_probe(void);
+ *
+ * Write 1s to the PFN field of Entry_Lo0 to see how many
+ * PA bits are implemented.  Assumes that interrupts are disabled.
+ */
+LEAF(mips_cp0_tlb_entry_lo_probe)
+	dmfc0	t0, MIPS_COP_0_TLB_LO0
+	li	v0, -64		/* all 1s except low 6 bits */
+	dmtc0	v0, MIPS_COP_0_TLB_LO0
+	COP0_SYNC
+	nop
+	nop
+	dmfc0	v0, MIPS_COP_0_TLB_LO0
+	dmtc0	t0, MIPS_COP_0_TLB_LO0
+	COP0_SYNC
+	nop
+#ifdef __mips_o32
+	nop
+#if BYTE_ORDER == BIG_ENDIAN
+	srl	v1, v0, 0
+	dsra	v0, v0, 32
+#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+	dsra	v1, v0, 32
+	srl	v0, v0, 0
+#endif
+#endif /* __mips_o32 */
+	j	ra
+	 nop
+END(mips_cp0_tlb_entry_lo_probe)
+	.set	pop
+
+/*
+ * uint32_t mips_cp0_tlb_page_mask_probe(void);
+ *
+ * Write 1s to the RPN field of Entry_Lo0 to see how many PA bits are implemented.
+ * Assumes that interrupts are disabled.
+ */
+LEAF(mips_cp0_tlb_page_mask_probe)
+	mfc0	t0, MIPS_COP_0_TLB_PG_MASK
+	lui	v0, 0xffff
+	srl	v0, v0, 3
+	mtc0	v0, MIPS_COP_0_TLB_PG_MASK
+	COP0_SYNC
+	nop
+	nop
+	mfc0	v0, MIPS_COP_0_TLB_PG_MASK
+	mtc0	t0, MIPS_COP_0_TLB_PG_MASK
+	COP0_SYNC
+	nop
+	j	ra
+	 nop
+END(mips_cp0_tlb_page_mask_probe)
+#endif /* MIPS3_PLUS */
 
 #if !defined(NOFPU) && !defined(SOFTFLOAT)
 /*----------------------------------------------------------------------------

Index: src/sys/arch/mips/mips/mips_machdep.c
diff -u src/sys/arch/mips/mips/mips_machdep.c:1.205.4.1.2.1.2.7 src/sys/arch/mips/mips/mips_machdep.c:1.205.4.1.2.1.2.8
--- src/sys/arch/mips/mips/mips_machdep.c:1.205.4.1.2.1.2.7	Tue Sep  8 08:11:29 2009
+++ src/sys/arch/mips/mips/mips_machdep.c	Fri Sep 11 23:51:25 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.7 2009/09/08 08:11:29 matt Exp $	*/
+/*	$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.8 2009/09/11 23:51:25 matt Exp $	*/
 
 /*
  * Copyright 2002 Wasabi Systems, Inc.
@@ -112,7 +112,7 @@
 
 #include <sys/cdefs.h>			/* RCS ID & Copyright macro defns */
 
-__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.7 2009/09/08 08:11:29 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mips_machdep.c,v 1.205.4.1.2.1.2.8 2009/09/11 23:51:25 matt Exp $");
 
 #include "opt_cputype.h"
 
@@ -166,6 +166,14 @@
 u_long	cpu_dump_mempagecnt(void);
 int	cpu_dump(void);
 
+#if defined(MIPS3_PLUS)
+uint32_t mips_cp0_tlb_page_mask_probe(void);
+uint64_t mips_cp0_tlb_entry_hi_probe(void);
+uint64_t mips_cp0_tlb_entry_lo_probe(void);
+
+static void mips3_tlb_probe(void);
+#endif
+
 #if defined(MIPS1)
 static void	mips1_vector_init(void);
 extern const struct locoresw mips1_locoresw;
@@ -206,6 +214,11 @@
 uint64_t mips3_xkphys_cached;
 #endif
 u_int mips3_pg_shift;
+#ifdef MIPS3_PLUS
+uint64_t mips3_tlb_vpn_mask;
+uint64_t mips3_tlb_pfn_mask;
+uint32_t mips3_tlb_pg_mask;
+#endif
 
 struct	user *proc0paddr;
 struct	segtab *segbase = (void *)(MIPS_KSEG2_START + 0x1eadbeef);
@@ -916,6 +929,7 @@
 	case CPU_ARCH_MIPS3:
 	case CPU_ARCH_MIPS4:
 #if defined(MIPS3_5900)	/* XXX */
+		mips3_tlb_probe();
 		mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_4K);
 		mips3_cp0_wired_write(0);
 		mips5900_TBIA(mips_num_tlb_entries);
@@ -923,6 +937,7 @@
 		r5900_vector_init();
 		mips_locoresw = mips5900_locoresw;
 #else /* MIPS3_5900 */
+		mips3_tlb_probe();
 #if defined(MIPS3_4100)
 		if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4100)
 			mips3_cp0_pg_mask_write(MIPS4100_PG_SIZE_4K);
@@ -948,7 +963,8 @@
 		break;
 #endif
 #if defined(MIPS64)
-	case CPU_ARCH_MIPS64:
+	case CPU_ARCH_MIPS64: {
+		mips3_tlb_probe();
 		mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_4K);
 		mips3_cp0_wired_write(0);
 		mips64_TBIA(mips_num_tlb_entries);
@@ -956,6 +972,7 @@
 		mips64_vector_init();
 		mips_locoresw = mips64_locoresw;
 		break;
+	}
 #endif
 	default:
 		printf("cpu_arch 0x%x: not supported\n", cpu_arch);
@@ -982,6 +999,20 @@
 	(*flush_fn)();
 }
 
+#ifdef MIPS3_PLUS
+static void
+mips3_tlb_probe(void)
+{
+	mips3_tlb_pg_mask = mips_cp0_tlb_page_mask_probe();
+	if (CPUIS64BITS) {
+		mips3_tlb_vpn_mask = mips_cp0_tlb_entry_hi_probe();
+		mips3_tlb_vpn_mask <<= 2;
+		mips3_tlb_vpn_mask >>= 2;
+		mips3_tlb_pfn_mask = mips_cp0_tlb_entry_lo_probe();
+	}
+}
+#endif
+
 /*
  * Identify product revision IDs of CPU and FPU.
  */
@@ -994,6 +1025,10 @@
 		"2-way set-associative",	/* 2 */
 		NULL,				/* 3 */
 		"4-way set-associative",	/* 4 */
+		"5-way set-associative",	/* 5 */
+		"6-way set-associative",	/* 6 */
+		"7-way set-associative",	/* 7 */
+		"8-way set-associative",	/* 8 */
 	};
 #define	nwaynames (sizeof(waynames) / sizeof(waynames[0]))
 	static const char * const wtnames[] = {
@@ -1087,14 +1122,39 @@
 	case CPU_ARCH_MIPS3:
 	case CPU_ARCH_MIPS4:
 	case CPU_ARCH_MIPS32:
-	case CPU_ARCH_MIPS64:
+	case CPU_ARCH_MIPS64: {
+		const char *sufx = "KMGTPE";
+		uint32_t pg_mask;
+		printf("%s: %d TLB entries", label, mips_num_tlb_entries);
+#if !defined(__mips_o32)
+		if (CPUIS64BITS) {
+			int64_t pfn_mask;
+			i = ffs(~(mips3_tlb_vpn_mask >> 31)) + 30;
+			printf(", %d%cB (%d-bit) VAs",
+			    1 << (i % 10), sufx[(i / 10) - 1], i);
+			for (i = 64, pfn_mask = mips3_tlb_pfn_mask;
+			     pfn_mask > 0; i--, pfn_mask <<= 1)
+				;
+			printf(", %d%cB (%d-bit) PAs",
+			      1 << (i % 10), sufx[(i / 10) - 1], i);
+		}
+#endif
+		for (i = 4, pg_mask = mips3_tlb_pg_mask >> 13;
+		     pg_mask != 0; ) {
+			if ((pg_mask & 3) != 3)
+				break;
+			pg_mask >>= 2;
+			i *= 4;
+			if (i == 1024) {
+				i = 1;
+				sufx++;
+			}
+		}
+		printf(", %d%cB max page size\n", i, sufx[0]);
 		if (mips_picache_size)
-			printf("%s: %dKB/%dB %s L1 Instruction cache, "
-			    "%d TLB entries\n", label, mips_picache_size / 1024,
-			    mips_picache_line_size, waynames[mips_picache_ways],
-			    mips_num_tlb_entries);
-		else
-			printf("%s: %d TLB entries\n", label, mips_num_tlb_entries);
+			printf("%s: %dKB/%dB %s L1 Instruction cache\n",
+			    label, mips_picache_size / 1024,
+			    mips_picache_line_size, waynames[mips_picache_ways]);
 		if (mips_pdcache_size)
 			printf("%s: %dKB/%dB %s %s L1 Data cache\n", label,
 			    mips_pdcache_size / 1024, mips_pdcache_line_size,
@@ -1107,6 +1167,7 @@
 			    wtnames[mips_sdcache_write_through],
 			    mips_scache_unified ? "Unified" : "Data");
 		break;
+	}
 #endif /* MIPS3 */
 	default:
 		panic("cpu_identify: impossible");

Reply via email to