Module Name:    src
Committed By:   mrg
Date:           Sun Aug 28 10:26:15 UTC 2011

Modified Files:
        src/sys/arch/sparc/sparc: pmap.c

Log Message:
fix sparc UP kernels with GCC 4.5, with special thanks to help from
mlelstv@ tracking down the real issue.

sp_tlb_flush() makes various assumptions about the ABI and what GCC
will do with the rest of this function.  the inputs were not referenced
by name but only as "%o0" etc inside the asm.  the result was that GCC
was not filling in the function parameters before calling it because
they were not used in the function.  so, sp_tlb_flush() was getting
random data for it's inputs.  oops.

for now, convert 2 asm() calls to pure C, and mark the inputs for
the sta calls.  this makes GCC generate the right code, but it still
isn't entirely optimal.

ideally a pure C version would exist, but that adds non-trivial
overhead (15 instructions vs 23 or so.)

one more enhancement to make here would be to assign the %o3, %o4 and
%o5 usage into explicit temp variables, instead of assuming that they
are going to be free to use.


To generate a diff of this commit:
cvs rdiff -u -r1.344 -r1.345 src/sys/arch/sparc/sparc/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/sparc/sparc/pmap.c
diff -u src/sys/arch/sparc/sparc/pmap.c:1.344 src/sys/arch/sparc/sparc/pmap.c:1.345
--- src/sys/arch/sparc/sparc/pmap.c:1.344	Wed Aug 24 02:51:13 2011
+++ src/sys/arch/sparc/sparc/pmap.c	Sun Aug 28 10:26:15 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: pmap.c,v 1.344 2011/08/24 02:51:13 mrg Exp $ */
+/*	$NetBSD: pmap.c,v 1.345 2011/08/28 10:26:15 mrg Exp $ */
 
 /*
  * Copyright (c) 1996
@@ -56,7 +56,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.344 2011/08/24 02:51:13 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.345 2011/08/28 10:26:15 mrg Exp $");
 
 #include "opt_ddb.h"
 #include "opt_kgdb.h"
@@ -614,12 +614,12 @@
 	__asm("lda	[%%o4]%0, %%o5" :: "n"(ASI_SRMMU));
 
 	/* Set new context and flush type bits */
-	__asm("andn	%o0, 0xfff, %o0");
-	__asm("sta	%%o1, [%%o4]%0" :: "n"(ASI_SRMMU));
-	__asm("or	%o0, %o2, %o0");
+	va &= ~0xfff;
+	__asm("sta	%1, [%%o4]%0" :: "n"(ASI_SRMMU), "r"(ctx));
+	va |= lvl;
 
 	/* Do the TLB flush */
-	__asm("sta	%%g0, [%%o0]%0" :: "n"(ASI_SRMMUFP));
+	__asm("sta	%%g0, [%1]%0" :: "n"(ASI_SRMMUFP), "r"(va));
 
 	/* Restore context */
 	__asm("sta	%%o5, [%%o4]%0" :: "n"(ASI_SRMMU));
@@ -689,7 +689,7 @@
 {
 
 	if (CPU_ISSUN4D) {
-		sp_tlb_flush(ctx, 0, ASI_SRMMUFP_L0);
+		sp_tlb_flush(0, ctx, ASI_SRMMUFP_L0);
 	} else
 		FXCALL3(sp_tlb_flush, ft_tlb_flush, 0, ctx, ASI_SRMMUFP_L0, cpuset);
 }
@@ -715,7 +715,7 @@
 #define tlb_flush_page(va,ctx,s)	sp_tlb_flush(va,ctx,ASI_SRMMUFP_L3)
 #define tlb_flush_segment(va,ctx,s)	sp_tlb_flush(va,ctx,ASI_SRMMUFP_L2)
 #define tlb_flush_region(va,ctx,s)	sp_tlb_flush(va,ctx,ASI_SRMMUFP_L1)
-#define tlb_flush_context(ctx,s)	sp_tlb_flush(ctx,0,ASI_SRMMUFP_L0)
+#define tlb_flush_context(ctx,s)	sp_tlb_flush(0,ctx,ASI_SRMMUFP_L0)
 #define tlb_flush_all()			sp_tlb_flush_all()
 #endif /* MULTIPROCESSOR */
 

Reply via email to