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 */