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); +}