Module Name:    src
Committed By:   mrg
Date:           Thu Mar  4 08:01:35 UTC 2010

Modified Files:
        src/sys/arch/sparc64/include: pmap.h
        src/sys/arch/sparc64/sparc64: locore.s machdep.c pmap.c

Log Message:
- in _bus_dmamap_unload(), pmap_page_protect() and pmap_clear_reference()
  switch the dcache_flush_page() into a dcache_flush_page_all()
- in both pmap_kremove()/pmap_remove(), remove the blast_dcache() call
  and replace it with dcache_flush_page_all()
- in pmap_get_page() [used to allocate PTP's], always call pmap_zero_page(pa)
- flush the dcache of the dst page in pmap_{copy,zero}_page() by redirecting
  throught a C function that calls the (renamed) asm.  the old asm code had a
  comment about needing to do this...
- add a couple of membar #Sync's that the USIII manual recommends

based on discussions with chuq@, skrll@ and mar...@.

these help my SB2000 / SB2500 with both disk / nfs builds and other tasks,
sometimes lasting for several hours before failing or asserting.


To generate a diff of this commit:
cvs rdiff -u -r1.50 -r1.51 src/sys/arch/sparc64/include/pmap.h
cvs rdiff -u -r1.321 -r1.322 src/sys/arch/sparc64/sparc64/locore.s
cvs rdiff -u -r1.251 -r1.252 src/sys/arch/sparc64/sparc64/machdep.c
cvs rdiff -u -r1.254 -r1.255 src/sys/arch/sparc64/sparc64/pmap.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/sparc64/include/pmap.h
diff -u src/sys/arch/sparc64/include/pmap.h:1.50 src/sys/arch/sparc64/include/pmap.h:1.51
--- src/sys/arch/sparc64/include/pmap.h:1.50	Wed Feb 24 04:48:28 2010
+++ src/sys/arch/sparc64/include/pmap.h	Thu Mar  4 08:01:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.h,v 1.50 2010/02/24 04:48:28 mrg Exp $	*/
+/*	$NetBSD: pmap.h,v 1.51 2010/03/04 08:01:35 mrg Exp $	*/
 
 /*-
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -204,6 +204,10 @@
 void		switchexit(struct lwp *, int);
 void		pmap_kprotect(vaddr_t, vm_prot_t);
 
+/* SPARC64 specific */
+void		pmap_copy_page_phys(paddr_t, paddr_t);
+void		pmap_zero_page_phys(paddr_t);
+
 /* Installed physical memory, as discovered during bootstrap. */
 extern int phys_installed_size;
 extern struct mem_region *phys_installed;

Index: src/sys/arch/sparc64/sparc64/locore.s
diff -u src/sys/arch/sparc64/sparc64/locore.s:1.321 src/sys/arch/sparc64/sparc64/locore.s:1.322
--- src/sys/arch/sparc64/sparc64/locore.s:1.321	Wed Feb 24 09:49:36 2010
+++ src/sys/arch/sparc64/sparc64/locore.s	Thu Mar  4 08:01:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: locore.s,v 1.321 2010/02/24 09:49:36 mrg Exp $	*/
+/*	$NetBSD: locore.s,v 1.322 2010/03/04 08:01:35 mrg Exp $	*/
 
 /*
  * Copyright (c) 1996-2002 Eduardo Horvath
@@ -203,10 +203,10 @@
  */
 #ifdef DCACHE_BUG
 #define DLFLUSH(a,t) \
-	andn	a, 0x1f, t; \
+	andn	a, 0x3f, t; \
 	stxa	%g0, [ t ] ASI_DCACHE_TAG; \
 	membar	#Sync
-/* The following can be used if the pointer is 16-byte aligned */
+/* The following can be used if the pointer is 32-byte aligned */
 #define DLFLUSH2(t) \
 	stxa	%g0, [ t ] ASI_DCACHE_TAG; \
 	membar	#Sync
@@ -775,7 +775,6 @@
 	TA32
 ufast_DMMU_miss:			! 068 = fast data access MMU miss
 	ldxa	[%g0] ASI_DMMU_8KPTR, %g2! Load DMMU 8K TSB pointer
-
 #ifdef NO_TSB
 	ba,a	%icc, data_miss
 #endif
@@ -4947,11 +4946,15 @@
 	membar	#Sync
 	or	%o0, DEMAP_PAGE_PRIMARY, %o0
 	stxa	%o0, [%o0] ASI_DMMU_DEMAP		! Do the demap
+	membar	#Sync
 	stxa	%o0, [%o0] ASI_IMMU_DEMAP		! to both TLBs
+	membar	#Sync
 #ifdef TLB_FLUSH_LOWVA
 	srl	%o0, 0, %o0				! and make sure it's both 32- and 64-bit entries
 	stxa	%o0, [%o0] ASI_DMMU_DEMAP		! Do the demap
+	membar	#Sync
 	stxa	%o0, [%o0] ASI_IMMU_DEMAP		! Do the demap
+	membar	#Sync
 #endif
 	flush	%o1
 	stxa	%o5, [%o2] ASI_DMMU			! Restore primary context
@@ -5050,6 +5053,7 @@
 	wrpr	%o4, 0, %pstate
 
 	stxa	%o2, [%o2] ASI_IMMU_DEMAP
+	membar	#Sync
 	stxa	%o2, [%o2] ASI_DMMU_DEMAP
 
 	sethi	%hi(KERNBASE), %o4
@@ -6566,22 +6570,19 @@
 	 membar	#StoreStore|#StoreLoad
 
 /*
- * pmap_zero_page(pa)
+ * pmap_zero_page_phys(pa)
  *
  * Zero one page physically addressed
  *
  * Block load/store ASIs do not exist for physical addresses,
  * so we won't use them.
  *
- * While we do the zero operation, we also need to blast away
- * the contents of the D$.  We will execute a flush at the end
- * to sync the I$.
+ * We will execute a flush at the end to sync the I$.
+ *
+ * This version expects to have the dcache_flush_page_all(pa)
+ * to have been called before calling into here.
  */
-	.data
-paginuse:
-	.word	0
-	.text
-ENTRY(pmap_zero_page)
+ENTRY(pmap_zero_page_phys)
 #ifndef _LP64
 	COMBINE(%o0, %o1, %o0)
 #endif
@@ -6625,7 +6626,7 @@
 	 wr	%g0, ASI_PRIMARY_NOFAULT, %asi	! Make C code happy
 
 /*
- * pmap_copy_page(paddr_t src, paddr_t dst)
+ * pmap_copy_page_phys(paddr_t src, paddr_t dst)
  *
  * Copy one page physically addressed
  * We need to use a global reg for ldxa/stxa
@@ -6634,10 +6635,11 @@
  * 32-bit stack.  We will unroll the loop by 4 to
  * improve performance.
  *
- * XXX We also need to blast the D$ and flush like
- * XXX pmap_zero_page.
+ * This version expects to have the dcache_flush_page_all(pa)
+ * to have been called before calling into here.
+ *
  */
-ENTRY(pmap_copy_page)
+ENTRY(pmap_copy_page_phys)
 #ifndef _LP64
 	COMBINE(%o0, %o1, %o0)
 	COMBINE(%o2, %o3, %o1)

Index: src/sys/arch/sparc64/sparc64/machdep.c
diff -u src/sys/arch/sparc64/sparc64/machdep.c:1.251 src/sys/arch/sparc64/sparc64/machdep.c:1.252
--- src/sys/arch/sparc64/sparc64/machdep.c:1.251	Mon Feb  8 19:02:32 2010
+++ src/sys/arch/sparc64/sparc64/machdep.c	Thu Mar  4 08:01:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: machdep.c,v 1.251 2010/02/08 19:02:32 joerg Exp $ */
+/*	$NetBSD: machdep.c,v 1.252 2010/03/04 08:01:35 mrg Exp $ */
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.251 2010/02/08 19:02:32 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.252 2010/03/04 08:01:35 mrg Exp $");
 
 #include "opt_ddb.h"
 #include "opt_multiprocessor.h"
@@ -1299,7 +1299,7 @@
 			 * We should be flushing a subrange, but we
 			 * don't know where the segments starts.
 			 */
-			dcache_flush_page(pa);
+			dcache_flush_page_all(pa);
 		}
 	}
 

Index: src/sys/arch/sparc64/sparc64/pmap.c
diff -u src/sys/arch/sparc64/sparc64/pmap.c:1.254 src/sys/arch/sparc64/sparc64/pmap.c:1.255
--- src/sys/arch/sparc64/sparc64/pmap.c:1.254	Wed Feb 24 10:11:53 2010
+++ src/sys/arch/sparc64/sparc64/pmap.c	Thu Mar  4 08:01:35 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.254 2010/02/24 10:11:53 mrg Exp $	*/
+/*	$NetBSD: pmap.c,v 1.255 2010/03/04 08:01:35 mrg Exp $	*/
 /*
  *
  * Copyright (C) 1996-1999 Eduardo Horvath.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.254 2010/02/24 10:11:53 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.255 2010/03/04 08:01:35 mrg Exp $");
 
 #undef	NO_VCACHE /* Don't forget the locked TLB in dostart */
 #define	HWREF
@@ -1608,11 +1608,10 @@
 		 */
 
 		tlb_flush_pte(va, pm);
+		dcache_flush_page_all(pa);
 	}
-	if (flush) {
+	if (flush)
 		REMOVE_STAT(flushes);
-		blast_dcache();
-	}
 }
 
 /*
@@ -1998,11 +1997,10 @@
 		tsb_invalidate(va, pm);
 		REMOVE_STAT(tflushes);
 		tlb_flush_pte(va, pm);
+		dcache_flush_page_all(pa);
 	}
-	if (flush && pm->pm_refs) {
+	if (flush && pm->pm_refs)
 		REMOVE_STAT(flushes);
-		blast_dcache();
-	}
 	DPRINTF(PDB_REMOVE, ("\n"));
 	pv_check();
 	mutex_exit(&pmap_lock);
@@ -2418,9 +2416,7 @@
 	int modified = 0;
 
 	DPRINTF(PDB_CHANGEPROT|PDB_REF, ("pmap_clear_modify(%p)\n", pg));
-#endif
 
-#if defined(DEBUG)
 	modified = pmap_is_modified(pg);
 #endif
 	mutex_enter(&pmap_lock);
@@ -2556,7 +2552,7 @@
 			}
 		}
 	}
-	dcache_flush_page(VM_PAGE_TO_PHYS(pg));
+	dcache_flush_page_all(VM_PAGE_TO_PHYS(pg));
 	pv_check();
 #ifdef DEBUG
 	if (pmap_is_referenced_locked(pg)) {
@@ -2924,9 +2920,8 @@
 				pv->pv_next = NULL;
 			}
 		}
-		if (needflush) {
-			dcache_flush_page(VM_PAGE_TO_PHYS(pg));
-		}
+		if (needflush)
+			dcache_flush_page_all(VM_PAGE_TO_PHYS(pg));
 	}
 	/* We should really only flush the pages we demapped. */
 	pv_check();
@@ -3624,3 +3619,28 @@
 	pmap->pm_refs = 1;
 	pmap_activate_pmap(pmap);
 }
+
+/*
+ * pmap_copy_page()/pmap_zero_page()
+ *
+ * we make sure that the destination page is flushed from all D$'s
+ * before we perform the copy/zero.
+ */
+extern int cold;
+void
+pmap_copy_page(paddr_t src, paddr_t dst)
+{
+
+	if (!cold)
+		dcache_flush_page_all(dst);
+	pmap_copy_page_phys(src, dst);
+}
+
+void
+pmap_zero_page(paddr_t pa)
+{
+
+	if (!cold)
+		dcache_flush_page_all(pa);
+	pmap_zero_page_phys(pa);
+}

Reply via email to