Subject: Re: "pmap_unwire: wiring ... didn't change!"
To: None <chuq@chuq.com>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-mips
Date: 09/01/2005 21:27:55
In article <20050830161048.GB12998@spathi.chuq.com>
chuq@chuq.com wrote:

> if we can remove the need to save/change/restore the pagemask
> in the common cases of creating and invalidating TLB entries,
> that would be a nice improvement, yea.

Well, I'm not a mips guru ;-p so there are some questions:
- MIPSX_TLBUpdate() does tlbr (which might modify the pagemask register),
  but in this function all TLBs have the default pagemask?
- MIPSX_TLBRead() might read a wired TLB entry, so we should restore
  pagemask before return?
- MIPSX_TBIAP() does tlbr but it won't read wired TLB entries,
  so no need to restore the default pagemask?
- MIPSX_TLBMissException() only happens non-wired TLB entries
  so no need to restore the default pagemask?

> note that even with that change, my mobilepro 880 still doesn't work.
> now it hangs even before printing the copyright (but after printing
> the mem_cluster stuff).

Hmm, it seems that MIPS3_4100 (which supports 1k page too?) requires
a special pagemask value. How about this one? (untested)

---
Index: sys/arch/mips/include/cpu.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/cpu.h,v
retrieving revision 1.73
diff -u -r1.73 cpu.h
--- sys/arch/mips/include/cpu.h	22 Sep 2004 11:32:03 -0000	1.73
+++ sys/arch/mips/include/cpu.h	1 Sep 2005 12:13:09 -0000
@@ -146,6 +146,7 @@
 extern int mips_has_r4k_mmu;
 extern int mips_has_llsc;
 extern int mips3_pg_cached;
+extern int mips3_has_1k_page;
 
 #define	CPU_MIPS_R4K_MMU		0x0001
 #define	CPU_MIPS_NO_LLSC		0x0002
@@ -194,6 +195,11 @@
 # define MIPS_HAS_R4K_MMU	1
 # define MIPS_HAS_CLOCK		1
 # define MIPS_HAS_LLSC		(mips_has_llsc)
+# if defined(MIPS3_4100)
+#  define MIPS3_HAS_1K_PAGE	(mips3_has_1k_page)
+# else
+#  define MIPS3_HAS_1K_PAGE	0
+# endif
 #endif /* MIPS3 || MIPS4 */
 
 #ifdef MIPS32
Index: sys/arch/mips/include/locore.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/locore.h,v
retrieving revision 1.68
diff -u -r1.68 locore.h
--- sys/arch/mips/include/locore.h	13 Feb 2004 11:36:15 -0000	1.68
+++ sys/arch/mips/include/locore.h	1 Sep 2005 12:13:09 -0000
@@ -119,6 +119,7 @@
 
 uint32_t mips3_cp0_wired_read(void);
 void	mips3_cp0_wired_write(uint32_t);
+void	mips3_cp0_pg_mask_write(uint32_t);
 
 uint64_t mips3_ld(uint64_t *);
 void	mips3_sd(uint64_t *, uint64_t);
Index: sys/arch/mips/include/mips3_pte.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/mips3_pte.h,v
retrieving revision 1.16
diff -u -r1.16 mips3_pte.h
--- sys/arch/mips/include/mips3_pte.h	7 Aug 2003 16:28:28 -0000	1.16
+++ sys/arch/mips/include/mips3_pte.h	1 Sep 2005 12:13:10 -0000
@@ -148,10 +148,9 @@
 	(MIPS3_PG_G | MIPS3_PG_V | MIPS3_PG_D | MIPS3_CCA_TO_PG(cca))
 #define	MIPS3_PG_FRAME	0x3fffffc0
 #ifdef MIPS3_4100			/* VR4100 core */
-#define MIPS3_PG_SHIFT	4
-#else
-#define MIPS3_PG_SHIFT	6
+#define MIPS4100_PG_SHIFT	4
 #endif
+#define MIPS3_PG_SHIFT	6
 
 /* pte accessor macros */
 
@@ -160,6 +159,12 @@
     (((paddr_t)(x) >> MIPS3_PG_SHIFT) & MIPS3_PG_FRAME)
 #define mips3_tlbpfn_to_paddr(x) \
     ((paddr_t)((x) & MIPS3_PG_FRAME) << MIPS3_PG_SHIFT)
+#if defined(MIPS3_4100)
+#define mips4100_paddr_to_tlbpfn(x) \
+    (((paddr_t)(x) >> MIPS4100_PG_SHIFT) & MIPS3_PG_FRAME)
+#define mips4100_tlbpfn_to_paddr(x) \
+    ((paddr_t)((x) & MIPS3_PG_FRAME) << MIPS4100_PG_SHIFT)
+#endif /* defined(MIPS3_4100) */
 #define mips3_vad_to_vpn(x) ((vaddr_t)(x) & MIPS3_PG_SVPN)
 #define mips3_vpn_to_vad(x) ((x) & MIPS3_PG_SVPN)
 
@@ -177,3 +182,16 @@
 #define	MIPS3_PG_SIZE_16M	0x01ffe000
 #define	MIPS3_PG_SIZE_64M	0x07ffe000
 #define	MIPS3_PG_SIZE_256M	0x1fffe000
+
+#if defined(MIPS3_4100)
+#define	MIPS4100_PG_SIZE_1K	0x00000000
+#define	MIPS4100_PG_SIZE_4K	0x00001800
+#define	MIPS4100_PG_SIZE_16K	0x00007800
+#define	MIPS4100_PG_SIZE_64K	0x0001f800
+#define	MIPS4100_PG_SIZE_256K	0x0007f800
+#define	MIPS4100_PG_SIZE_1M	0x001ff800
+#define	MIPS4100_PG_SIZE_4M	0x007ff800
+#define	MIPS4100_PG_SIZE_16M	0x01fff800
+#define	MIPS4100_PG_SIZE_64M	0x07fff800
+#define	MIPS4100_PG_SIZE_256M	0x1ffff800
+#endif /* defined(MIPS3_4100) */
Index: sys/arch/mips/include/pte.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/pte.h,v
retrieving revision 1.13
diff -u -r1.13 pte.h
--- sys/arch/mips/include/pte.h	14 Oct 2002 05:11:23 -0000	1.13
+++ sys/arch/mips/include/pte.h	1 Sep 2005 12:13:10 -0000
@@ -116,8 +116,15 @@
 #define	PTE_TO_PADDR(pte)	MIPS3_PTE_TO_PADDR((pte))
 #define	PAGE_IS_RDONLY(pte, va)	MIPS3_PAGE_IS_RDONLY((pte), (va))
 
+#if defined(MIPS3_4100)
+#define	mips_tlbpfn_to_paddr(x)		(MIPS3_HAS_1K_PAGE ?	\
+    mips4100_tlbpfn_to_paddr((vaddr_t)(x)) : mips3_tlbpfn_to_paddr((vaddr_t)(x))
+#define	mips_paddr_to_tlbpfn(x)		(MIPS3_HAS_1K_PAGE ?	\
+    mips4100_paddr_to_tlbpfn((x)) : mips3_paddr_to_tlbpfn((x))
+#else
 #define	mips_tlbpfn_to_paddr(x)		mips3_tlbpfn_to_paddr((vaddr_t)(x))
 #define	mips_paddr_to_tlbpfn(x)		mips3_paddr_to_tlbpfn((x))
+#endif /* defined(MIPS3_4100) */
 #endif /* mips3 */
 
 /* MIPS1 and MIPS3 (or greater) */
Index: sys/arch/mips/mips/locore_mips3.S
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/locore_mips3.S,v
retrieving revision 1.86
diff -u -r1.86 locore_mips3.S
--- sys/arch/mips/mips/locore_mips3.S	7 Aug 2003 16:28:32 -0000	1.86
+++ sys/arch/mips/mips/locore_mips3.S	1 Sep 2005 12:13:10 -0000
@@ -393,6 +393,20 @@
 	nop
 END(mips3_cp0_wired_write)
 
+/*
+ * void mips3_cp0_pg_mask_write(u_int32_t)
+ *
+ *	Set the value of the CP0 PG_MASK register.
+ */
+LEAF(mips3_cp0_pg_mask_write)
+	mtc0	a0, MIPS_COP_0_TLB_PG_MASK
+	COP0_SYNC
+	nop
+	nop
+	j	ra
+	nop
+END(mips3_cp0_pg_mask_write)
+
 #if defined(_MIPS_BSD_API) && \
     (_MIPS_BSD_API == _MIPS_BSD_API_N32 || _MIPS_BSD_API == _MIPS_BSD_API_LP64)
 #error mips3_ld and mips3_sd should be adjusted for N32 or LP64
Index: sys/arch/mips/mips/mipsX_subr.S
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mipsX_subr.S,v
retrieving revision 1.16
diff -u -r1.16 mipsX_subr.S
--- sys/arch/mips/mips/mipsX_subr.S	30 Apr 2005 15:56:32 -0000	1.16
+++ sys/arch/mips/mips/mipsX_subr.S	1 Sep 2005 12:13:10 -0000
@@ -134,7 +134,6 @@
 
 /*
  * XXX MIPS3_5900 is still "special" for much of this code.
- * XXX MIPS3_4100 is still "special" in tlb update code
  */
 
 #if MIPS1
@@ -1709,8 +1708,10 @@
 	mtc0	zero, MIPS_COP_0_STATUS		# Disable interrupts
 	COP0_SYNC
 	nop
+#if defined(MIPS3) && defined(MIPS3_4100)
 	mfc0	ta2, MIPS_COP_0_TLB_PG_MASK	# save current pgMask
 	nop
+#endif
 	_MFC0	t0, MIPS_COP_0_TLB_HI		# Get current PID
 
 	mtc0	a0, MIPS_COP_0_TLB_INDEX	# Set the index register
@@ -1728,7 +1729,11 @@
 	_MFC0	ta1, MIPS_COP_0_TLB_LO1		# See what we got
 	_MTC0	t0, MIPS_COP_0_TLB_HI		# restore PID
 	COP0_SYNC
+#if defined(MIPS3) && defined(MIPS3_4100)
 	mtc0	ta2, MIPS_COP_0_TLB_PG_MASK	# restore pgMask
+#else
+	mtc0	zero, MIPS_COP_0_TLB_PG_MASK	# restore pgMask
+#endif
 	COP0_SYNC
 	nop
 	nop
@@ -2004,7 +2009,9 @@
 
 	li	v0, (MIPS3_PG_HVPN | MIPS3_PG_ASID)
 	_MFC0	t0, MIPS_COP_0_TLB_HI		# save current ASID
+#if defined(MIPS3) && defined(MIPS3_4100)
 	mfc0	t3, MIPS_COP_0_TLB_PG_MASK	# save current pgMask
+#endif
 	and	a0, a0, v0			# make sure valid entryHi
 	_MTC0	a0, MIPS_COP_0_TLB_HI		# look for the vaddr & ASID
 	COP0_SYNC
@@ -2038,8 +2045,10 @@
 1:
 	_MTC0	t0, MIPS_COP_0_TLB_HI		# restore current ASID
 	COP0_SYNC
+#if defined(MIPS3) && defined(MIPS3_4100)
 	mtc0	t3, MIPS_COP_0_TLB_PG_MASK	# restore pgMask
 	COP0_SYNC
+#endif
 	nop
 	nop
 	j	ra
@@ -2061,7 +2070,9 @@
 	move	t2, a0
 	mfc0	t1, MIPS_COP_0_TLB_WIRED
 	li	v0, MIPS_KSEG0_START		# invalid address
+#if defined(MIPS3) && defined(MIPS3_4100)
 	mfc0	t3, MIPS_COP_0_TLB_PG_MASK	# save current pgMask
+#endif
 
 	# do {} while (t1 < t2)
 1:
@@ -2100,11 +2111,13 @@
 	bne	t1, t2, 1b
 	nop
 
+#if defined(MIPS3) && defined(MIPS3_4100)
 	mtc0	t3, MIPS_COP_0_TLB_PG_MASK	# restore pgMask
 	COP0_SYNC
 	/* XXX simonb: lose these nops for mips32/64? */
 	nop
 	nop
+#endif
 	j	ra				# new ASID will be set soon
 	mtc0	v1, MIPS_COP_0_STATUS		# restore status register
 	COP0_SYNC				# XXXX - not executed!!
@@ -2123,7 +2136,9 @@
 	li	v0, MIPS_KSEG0_START		# invalid address
 	_MFC0	t0, MIPS_COP_0_TLB_HI		# save current ASID
 	mfc0	t1, MIPS_COP_0_TLB_WIRED
+#if defined(MIPS3) && defined(MIPS3_4100)
 	mfc0	t2, MIPS_COP_0_TLB_PG_MASK	# save current pgMask
+#endif
 
 	_MTC0	zero, MIPS_COP_0_TLB_LO0	# zero out entryLo0
 	COP0_SYNC
@@ -2150,8 +2165,10 @@
 
 	_MTC0	t0, MIPS_COP_0_TLB_HI		# restore ASID
 	COP0_SYNC
+#if defined(MIPS3) && defined(MIPS3_4100)
 	mtc0	t2, MIPS_COP_0_TLB_PG_MASK	# restore pgMask
 	COP0_SYNC
+#endif
 	nop
 	nop
 	j	ra
Index: sys/arch/mips/mips/mips_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mips_machdep.c,v
retrieving revision 1.178
diff -u -r1.178 mips_machdep.c
--- sys/arch/mips/mips/mips_machdep.c	1 Jun 2005 16:53:07 -0000	1.178
+++ sys/arch/mips/mips/mips_machdep.c	1 Sep 2005 12:13:11 -0000
@@ -208,6 +208,7 @@
 int mips_has_llsc;
 int mips_has_r4k_mmu;
 int mips3_pg_cached;
+int mips3_has_1k_page;
 
 struct	user *proc0paddr;
 struct	lwp  *fpcurlwp;
@@ -216,10 +217,6 @@
 
 caddr_t	msgbufaddr;
 
-#if defined(MIPS3_4100)			/* VR4100 core */
-int	default_pg_mask = 0x00001800;
-#endif
-
 /* the following is used externally (sysctl_hw) */
 char	machine[] = MACHINE;		/* from <machine/param.h> */
 char	machine_arch[] = MACHINE_ARCH;	/* from <machine/param.h> */
@@ -861,6 +858,11 @@
 	} else
 		mips3_pg_cached = MIPS3_DEFAULT_PG_CACHED;
 
+#if defined(MIPS3) && defined(MIPS3_4100)
+	if (MIPS_PRID_IMPL(cpu_id) == MIPS_R4100)
+		mips3_has_1k_page = 1;
+#endif
+
 #ifdef __HAVE_MIPS_MACHDEP_CACHE_CONFIG
 	mips_machdep_cache_config();
 #endif
@@ -886,12 +888,19 @@
 	case CPU_ARCH_MIPS3:
 	case CPU_ARCH_MIPS4:
 #if defined(MIPS3_5900)	/* XXX */
+		mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_4K);
 		mips3_cp0_wired_write(0);
 		mips5900_TBIA(mips_num_tlb_entries);
 		mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES);
 		r5900_vector_init();
 		memcpy(mips_locoresw, mips5900_locoresw, sizeof(mips_locoresw));
 #else /* MIPS3_5900 */
+#if defined(MIPS3_4100)
+		mips3_cp0_pg_mask_write(mips3_has_1k_page ?
+		    MIPS4100_PG_SIZE_4K : MIPS3_PG_SIZE_4K);
+#else /* MIPS3_4100 */
+		mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_4K);
+#endif /* MIPS3_4100 */
 		mips3_cp0_wired_write(0);
 		mips3_TBIA(mips_num_tlb_entries);
 		mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES);
@@ -902,6 +911,7 @@
 #endif
 #if defined(MIPS32)
 	case CPU_ARCH_MIPS32:
+		mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_4K);
 		mips3_cp0_wired_write(0);
 		mips32_TBIA(mips_num_tlb_entries);
 		mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES);
@@ -911,6 +921,7 @@
 #endif
 #if defined(MIPS64)
 	case CPU_ARCH_MIPS64:
+		mips3_cp0_pg_mask_write(MIPS3_PG_SIZE_4K);
 		mips3_cp0_wired_write(0);
 		mips64_TBIA(mips_num_tlb_entries);
 		mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES);
---
Izumi Tsutsui