Subject: Re: "pmap_unwire: wiring ... didn't change!"
To: None <port-cobalt@NetBSD.org>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: port-cobalt
Date: 02/26/2005 19:03:05
In article <16928.17339.556944.328650@basis.lke.rad.klinikum.rwth-aachen.de>
kilbi@rad.rwth-aachen.de wrote:

>     Izumi> With the attached (a bit ugly) patch against cache.c (which
>     Izumi> make always wbinv use index ops) the problem seems
>     Izumi> disappear, but I'm not sure what is the real problem.
> 
> I've just tried this patch on my qube2: It seems to avoid the problem
> in pure read situation ('cmp', 'sha1' et al.), but I still can
> reproduce corruptions if doing 'cp file1 fileN' multiple times...

Hmm.

I'm also using another patch as workaround for virtual alias problem.
Could you try this one?
---
Izumi Tsutsui
tsutsui@ceres.dti.ne.jp


Index: arch/mips/include/cache.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/include/cache.h,v
retrieving revision 1.6
diff -u -r1.6 cache.h
--- arch/mips/include/cache.h	17 Feb 2003 11:35:01 -0000	1.6
+++ arch/mips/include/cache.h	26 Feb 2005 09:48:22 -0000
@@ -199,6 +199,8 @@
 extern u_int mips_cache_alias_mask;
 extern u_int mips_cache_prefer_mask;
 
+extern int mips_cache_virtual_alias;
+
 /*
  * XXX XXX XXX THIS SHOULD NOT EXIST XXX XXX XXX
  */
Index: arch/mips/mips/cache.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/cache.c,v
retrieving revision 1.25
diff -u -r1.25 cache.c
--- arch/mips/mips/cache.c	13 Dec 2004 08:39:21 -0000	1.25
+++ arch/mips/mips/cache.c	26 Feb 2005 09:48:22 -0000
@@ -152,6 +152,8 @@
 u_int mips_cache_alias_mask;	/* for virtually-indexed caches */
 u_int mips_cache_prefer_mask;
 
+int mips_cache_virtual_alias;
+
 struct mips_cache_ops mips_cache_ops;
 
 #ifdef MIPS1
@@ -419,6 +421,11 @@
 
 		mips3_get_cache_config(csizebase);
 
+		if (mips_picache_size > PAGE_SIZE ||
+		    mips_pdcache_size > PAGE_SIZE)
+			/* no VCE support if there is no L2 cache */
+			mips_cache_virtual_alias = 1;
+
 		switch (mips_picache_line_size) {
 		case 16:
 			mips_cache_ops.mco_icache_sync_all =
@@ -492,6 +499,10 @@
 
 		mips3_get_cache_config(csizebase);
 
+		if (mips_picache_size > PAGE_SIZE ||
+		    mips_pdcache_size > PAGE_SIZE)
+			mips_cache_virtual_alias = 1;
+
 		switch (mips_picache_line_size) {
 		case 32:
 			mips_cache_ops.mco_icache_sync_all =
@@ -512,7 +523,11 @@
 			mips_cache_ops.mco_pdcache_wbinv_all =
 			    r5k_pdcache_wbinv_all_16;
 			mips_cache_ops.mco_pdcache_wbinv_range =
+#if 0
 			    r5k_pdcache_wbinv_range_16;
+#else
+			    r5k_pdcache_wbinv_range_index_16; /* XXX XXX XXX */
+#endif
 			mips_cache_ops.mco_pdcache_wbinv_range_index =
 			    r5k_pdcache_wbinv_range_index_16;
 			mips_cache_ops.mco_pdcache_inv_range =
@@ -525,7 +540,11 @@
 			mips_cache_ops.mco_pdcache_wbinv_all =
 			    r5k_pdcache_wbinv_all_32;
 			mips_cache_ops.mco_pdcache_wbinv_range =
+#if 0
 			    r5k_pdcache_wbinv_range_32;
+#else
+			    r5k_pdcache_wbinv_range_index_32; /* XXX XXX XXX */
+#endif
 			mips_cache_ops.mco_pdcache_wbinv_range_index =
 			    r5k_pdcache_wbinv_range_index_32;
 			mips_cache_ops.mco_pdcache_inv_range =
@@ -588,6 +607,7 @@
 		    ~(PAGE_SIZE - 1);
 		mips_cache_prefer_mask =
 		    max(mips_pdcache_size, mips_picache_size) - 1;
+		mips_cache_virtual_alias = 1;
 		/* cache ops */
 		mips_cache_ops.mco_icache_sync_all =
 		    r5900_icache_sync_all_64;
@@ -617,6 +637,8 @@
 
 		mips4_get_cache_config(csizebase);
 
+		/* VCE is handled by hardware */
+
 		mips_cache_ops.mco_icache_sync_all =
 		    r10k_icache_sync_all;
 		mips_cache_ops.mco_icache_sync_range =
@@ -675,6 +697,7 @@
 		mips_cache_alias_mask =
 			(MIPS3_MAX_PCACHE_SIZE - 1) & ~(PAGE_SIZE - 1);
 		mips_cache_prefer_mask = MIPS3_MAX_PCACHE_SIZE - 1;
+		mips_cache_virtual_alias = 0;
 		/* FALLTHROUGH */
 	case MIPS_R4600:
 #ifdef ENABLE_MIPS_R4700
Index: arch/mips/mips/mem.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mem.c,v
retrieving revision 1.29
diff -u -r1.29 mem.c
--- arch/mips/mips/mem.c	7 Aug 2003 16:28:33 -0000	1.29
+++ arch/mips/mips/mem.c	26 Feb 2005 09:48:22 -0000
@@ -76,6 +76,9 @@
  * Memory special file
  */
 
+#include "opt_cputype.h"
+#include "opt_mips_cache.h"
+
 #include <sys/cdefs.h>
 __KERNEL_RCSID(0, "$NetBSD: mem.c,v 1.29 2003/08/07 16:28:33 agc Exp $");
 
@@ -89,6 +92,8 @@
 
 #include <machine/cpu.h>
 
+#include <mips/cache.h>
+
 #include <uvm/uvm_extern.h>
 
 extern paddr_t avail_end;
@@ -142,6 +147,8 @@
 				return (EFAULT);
 			v += MIPS_KSEG0_START;
 			error = uiomove((void *)v, c, uio);
+			if (MIPS_HAS_R4K_MMU)
+				mips_dcache_wbinv_range_index(v, c);
 			continue;
 
 		case DEV_KMEM:
@@ -156,6 +163,8 @@
 			    uio->uio_rw == UIO_READ ? B_READ : B_WRITE)))
 				return (EFAULT);
 			error = uiomove((void *)v, c, uio);
+			if (MIPS_HAS_R4K_MMU)
+				mips_dcache_wbinv_range_index(v, c);
 			continue;
 
 		case DEV_NULL:
Index: arch/mips/mips/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/pmap.c,v
retrieving revision 1.156
diff -u -r1.156 pmap.c
--- arch/mips/mips/pmap.c	17 Jan 2005 04:54:14 -0000	1.156
+++ arch/mips/mips/pmap.c	26 Feb 2005 09:48:23 -0000
@@ -643,8 +643,8 @@
 			 * is reused with KSEG2 (mapped) addresses.  This may
 			 * cause problems on machines without secondary caches.
 			 */
-			if (MIPS_HAS_R4K_MMU)
-				mips_dcache_wbinv_range((vaddr_t) pte,
+			if (mips_cache_virtual_alias)
+				mips_dcache_inv_range((vaddr_t) pte,
 				    PAGE_SIZE);
 #endif	/* MIPS3_PLUS */
 			uvm_pagefree(PHYS_TO_VM_PAGE(MIPS_KSEG0_TO_PHYS(pte)));
@@ -1598,7 +1598,7 @@
 	 *
 	 * XXXJRT This is totally disgusting.
 	 */
-	if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0)
+	if (MIPS_HAS_R4K_MMU) /* XXX VCED on kernel stack is not allowed */
 		mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(phys), NBPG);
 #endif	/* MIPS3_PLUS */
 }
@@ -1635,10 +1635,12 @@
 	 * It would probably be better to map the destination as a
 	 * write-through no allocate to reduce cache thrash.
 	 */
-	if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) {
+	if (mips_cache_virtual_alias) {
 		/*XXX FIXME Not very sophisticated */
 		mips_flushcache_allpvh(src);
-/*		mips_flushcache_allpvh(dst); */
+#if 0
+		mips_flushcache_allpvh(dst);
+#endif
 	}
 #endif	/* MIPS3_PLUS */
 
@@ -1657,7 +1659,7 @@
 	 *
 	 * XXXJRT -- This is totally disgusting.
 	 */
-	if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) {
+	if (mips_cache_virtual_alias) {
 		mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(src), NBPG);
 		mips_dcache_wbinv_range(MIPS_PHYS_TO_KSEG0(dst), NBPG);
 	}
@@ -1888,7 +1890,7 @@
 		pv->pv_next = NULL;
 	} else {
 #if defined(MIPS3_PLUS) /* XXX mmu XXX */
-		if (MIPS_HAS_R4K_MMU && mips_sdcache_line_size == 0) {
+		if (mips_cache_virtual_alias) {
 			/*
 			 * There is at least one other VA mapping this page.
 			 * Check if they are cache index compatible.
@@ -2086,7 +2088,7 @@
 			pmap_page_cache(pa, 0);
 	}
 #endif
-	if (MIPS_HAS_R4K_MMU && last != 0)
+	if (last != 0 && mips_cache_virtual_alias)
 		mips_dcache_wbinv_range_index(va, PAGE_SIZE);
 #endif	/* MIPS3_PLUS */
 }
@@ -2116,6 +2118,11 @@
 void
 pmap_pv_page_free(struct pool *pp, void *v)
 {
+
+#ifdef MIPS3_PLUS
+	if (mips_cache_virtual_alias)
+		mips_dcache_inv_range((vaddr_t)v, PAGE_SIZE);
+#endif
 	uvm_pagefree(PHYS_TO_VM_PAGE(MIPS_KSEG0_TO_PHYS((vaddr_t)v)));
 }
 
Index: arch/mips/mips/vm_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/vm_machdep.c,v
retrieving revision 1.105
diff -u -r1.105 vm_machdep.c
--- arch/mips/mips/vm_machdep.c	1 Jan 2005 03:25:46 -0000	1.105
+++ arch/mips/mips/vm_machdep.c	26 Feb 2005 09:48:23 -0000
@@ -131,18 +131,6 @@
 	pt_entry_t *pte;
 	int i, x;
 
-#ifdef MIPS3_PLUS
-	/*
-	 * To eliminate virtual aliases created by pmap_zero_page(),
-	 * this cache flush operation is necessary.
-	 * VCED on kernel stack is not allowed.
-	 * XXXJRT Confirm that this is necessry, and/or fix
-	 * XXXJRT pmap_zero_page().
-	 */
-	if (CPUISMIPS3 && mips_sdcache_line_size)
-		mips_dcache_wbinv_range((vaddr_t) l2->l_addr, USPACE);
-#endif
-
 #ifdef DIAGNOSTIC
 	/*
 	 * If l1 != curlwp && l1 == &lwp0, we're creating a kernel thread.
@@ -333,7 +321,8 @@
 		if (pmap_extract(upmap, uva, &pa) == FALSE)
 			panic("vmapbuf: null page frame");
 		pmap_enter(vm_map_pmap(phys_map), kva, pa,
-		    VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
+		    VM_PROT_READ | VM_PROT_WRITE,
+		    VM_PROT_READ | VM_PROT_WRITE | PMAP_WIRED);
 		uva += PAGE_SIZE;
 		kva += PAGE_SIZE;
 		len -= PAGE_SIZE;