Module Name: src
Committed By: riz
Date: Wed Mar 21 16:10:22 UTC 2012
Modified Files:
src/sys/arch/sparc64/sparc64 [netbsd-6]: locore.s trap.c
Log Message:
Pull up following revision(s) (requested by mrg in ticket #131):
sys/arch/sparc64/sparc64/trap.c: revision 1.170
sys/arch/sparc64/sparc64/trap.c: revision 1.171
sys/arch/sparc64/sparc64/locore.s: revision 1.341
port the corrected ECC error handling code from freebsd. i noticed my U10
took one of these and then hang. it shouldn't hang, there's a 'sir' here that
doesn't seem to reset properly. oh well.
tested by simulated a trap via 'ta 0x10' and considering that the same, but
it hasn't been tested against a real ECC error yet.
count ECC corrected traps with evcnt(9).
To generate a diff of this commit:
cvs rdiff -u -r1.338.8.1 -r1.338.8.2 src/sys/arch/sparc64/sparc64/locore.s
cvs rdiff -u -r1.168 -r1.168.8.1 src/sys/arch/sparc64/sparc64/trap.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/sparc64/locore.s
diff -u src/sys/arch/sparc64/sparc64/locore.s:1.338.8.1 src/sys/arch/sparc64/sparc64/locore.s:1.338.8.2
--- src/sys/arch/sparc64/sparc64/locore.s:1.338.8.1 Mon Mar 5 20:59:25 2012
+++ src/sys/arch/sparc64/sparc64/locore.s Wed Mar 21 16:10:21 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.s,v 1.338.8.1 2012/03/05 20:59:25 sborrill Exp $ */
+/* $NetBSD: locore.s,v 1.338.8.2 2012/03/21 16:10:21 riz Exp $ */
/*
* Copyright (c) 2006-2010 Matthew R. Green
@@ -491,7 +491,7 @@ _C_LABEL(trapbase):
VTRAP(0x060, interrupt_vector); ! 060 = interrupt vector
TRAP(T_PA_WATCHPT) ! 061 = physical address data watchpoint
TRAP(T_VA_WATCHPT) ! 062 = virtual address data watchpoint
- UTRAP(T_ECCERR) ! We'll implement this one later
+ TRAP(T_ECCERR) ! 063 = corrected ECC error
ufast_IMMU_miss: ! 064 = fast instr access MMU miss
ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer
#ifdef NO_TSB
@@ -727,7 +727,7 @@ kdatafault:
VTRAP(0x060, interrupt_vector); ! 060 = interrupt vector
TRAP(T_PA_WATCHPT) ! 061 = physical address data watchpoint
TRAP(T_VA_WATCHPT) ! 062 = virtual address data watchpoint
- UTRAP(T_ECCERR) ! We'll implement this one later
+ TRAP(T_ECCERR) ! 063 = corrected ECC error
kfast_IMMU_miss: ! 064 = fast instr access MMU miss
ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer
#ifdef NO_TSB
Index: src/sys/arch/sparc64/sparc64/trap.c
diff -u src/sys/arch/sparc64/sparc64/trap.c:1.168 src/sys/arch/sparc64/sparc64/trap.c:1.168.8.1
--- src/sys/arch/sparc64/sparc64/trap.c:1.168 Sat Jul 30 19:29:12 2011
+++ src/sys/arch/sparc64/sparc64/trap.c Wed Mar 21 16:10:21 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.168 2011/07/30 19:29:12 martin Exp $ */
+/* $NetBSD: trap.c,v 1.168.8.1 2012/03/21 16:10:21 riz Exp $ */
/*
* Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
@@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.168 2011/07/30 19:29:12 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.168.8.1 2012/03/21 16:10:21 riz Exp $");
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
@@ -94,6 +94,8 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.1
#include <machine/svr4_32_machdep.h>
#endif
+#include <sparc64/sparc64/cache.h>
+
#include <sparc/fpu/fpu_extern.h>
#ifndef offsetof
@@ -159,6 +161,10 @@ int trapdebug = 0/*|TDB_SYSCALL|TDB_STOP
#define Debugger()
#endif
+struct evcnt ecc_corrected =
+ EVCNT_INITIALIZER(EVCNT_TYPE_MISC,0,"ECC","corrected");
+EVCNT_ATTACH_STATIC(ecc_corrected);
+
/*
* Initial FPU state is all registers == all 1s, everything else == all 0s.
* This makes every floating point register a signalling NaN, with sign bit
@@ -371,6 +377,7 @@ void text_access_fault(struct trapframe6
u_long sfsr);
void text_access_error(struct trapframe64 *, unsigned int, vaddr_t, u_long,
vaddr_t, u_long);
+void ecc_corrected_error(unsigned int type, vaddr_t pc);
#ifdef DEBUG
void print_trapframe(struct trapframe64 *);
@@ -540,6 +547,9 @@ trap(struct trapframe64 *tf, unsigned in
/* Enable the FPU */
tf->tf_tstate |= TSTATE_PEF;
return;
+ } else if (type == T_ECCERR) {
+ ecc_corrected_error(type, pc);
+ return;
}
goto dopanic;
}
@@ -855,6 +865,9 @@ badtrap:
ksi.ksi_code = FPE_INTOVF;
ksi.ksi_addr = (void *)pc;
break;
+ case T_ECCERR:
+ ecc_corrected_error(type, pc);
+ break;
}
if (sig != 0) {
ksi.ksi_signo = sig;
@@ -1622,3 +1635,48 @@ out:
}
#endif
}
+
+/*
+ * Handle an ECC corrected event.
+ */
+void
+ecc_corrected_error(unsigned int type, vaddr_t pc)
+{
+ uint64_t eeer, afar, afsr;
+ char buf[128];
+ int s;
+
+ /* Clear the error */
+ eeer = ldxa(0, ASI_ERROR_EN_REG);
+ s = intr_disable();
+ stxa(0, ASI_ERROR_EN_REG,
+ eeer & ~(P_EER_NCEEN | P_EER_CEEN));
+ membar_Sync();
+ intr_restore(s);
+
+ /* Flush the caches in order ensure no corrupt data got installed. */
+ blast_dcache();
+ blast_icache();
+
+#if 0
+ /* Ensure the caches are still turned on (should be). */
+ cache_enable(PCPU_GET(impl));
+#endif
+
+ /* Grab the current AFSR/AFAR, and clear the error from the AFSR. */
+ afar = ldxa(0, ASI_AFAR);
+ afsr = ldxa(0, ASI_AFSR);
+ s = intr_disable();
+ stxa(0, ASI_AFSR, ldxa(0, ASI_AFSR));
+ membar_Sync();
+ intr_restore(s);
+ ecc_corrected.ev_count++;
+ snprintb(buf, sizeof(buf), AFSR_BITS, afsr);
+ printf("corrected ECC error: pc %p afsr %"PRIx64" (%s) addr %"PRIx64"\n", (void *)pc, afsr, buf, afar);
+
+ /* Turn (non-)correctable error reporting back on. */
+ s = intr_disable();
+ stxa(0, ASI_ERROR_EN_REG, eeer);
+ membar_Sync();
+ intr_restore(s);
+}