Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sparc/sparc fix sparc UP kernels with GCC 4.5, with...



details:   https://anonhg.NetBSD.org/src/rev/631528fd31f2
branches:  trunk
changeset: 768879:631528fd31f2
user:      mrg <mrg%NetBSD.org@localhost>
date:      Sun Aug 28 10:26:15 2011 +0000

description:
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.

diffstat:

 sys/arch/sparc/sparc/pmap.c |  16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diffs (53 lines):

diff -r 994b9be07ce7 -r 631528fd31f2 sys/arch/sparc/sparc/pmap.c
--- a/sys/arch/sparc/sparc/pmap.c       Sun Aug 28 10:21:41 2011 +0000
+++ b/sys/arch/sparc/sparc/pmap.c       Sun Aug 28 10:26:15 2011 +0000
@@ -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 */
 



Home | Main Index | Thread Index | Old Index