Index: sparc64/locore.s =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/locore.s,v retrieving revision 1.340 diff -p -r1.340 locore.s *** sparc64/locore.s 3 Mar 2012 03:17:32 -0000 1.340 --- sparc64/locore.s 17 Mar 2012 20:49:39 -0000 *************** _C_LABEL(trapbase): *** 491,497 **** 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 ufast_IMMU_miss: ! 064 = fast instr access MMU miss ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer #ifdef NO_TSB --- 491,497 ---- 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 ! 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 *************** kdatafault: *** 727,733 **** 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 kfast_IMMU_miss: ! 064 = fast instr access MMU miss ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer #ifdef NO_TSB --- 727,733 ---- 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 ! 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: sparc64/trap.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/trap.c,v retrieving revision 1.169 diff -p -r1.169 trap.c *** sparc64/trap.c 19 Feb 2012 21:06:31 -0000 1.169 --- sparc64/trap.c 17 Mar 2012 20:49:39 -0000 *************** __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.1 *** 92,97 **** --- 92,99 ---- #include #endif + #include + #include #ifndef offsetof *************** void text_access_fault(struct trapframe6 *** 369,374 **** --- 371,377 ---- 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 *); *************** trap(struct trapframe64 *tf, unsigned in *** 538,543 **** --- 541,549 ---- /* Enable the FPU */ tf->tf_tstate |= TSTATE_PEF; return; + } else if (type == T_ECCERR) { + ecc_corrected_error(type, pc); + return; } goto dopanic; } *************** badtrap: *** 853,858 **** --- 859,867 ---- 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; *************** out: *** 1609,1611 **** --- 1618,1665 ---- } #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); + /* XXX: count the error */ + 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); + }