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