Wed Mar 21 16:10:22 2012 UTC ()
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).


(riz)
diff -r1.338.8.1 -r1.338.8.2 src/sys/arch/sparc64/sparc64/locore.s
diff -r1.168 -r1.168.8.1 src/sys/arch/sparc64/sparc64/trap.c

cvs diff -r1.338.8.1 -r1.338.8.2 src/sys/arch/sparc64/sparc64/locore.s (expand / switch to unified diff)

--- src/sys/arch/sparc64/sparc64/locore.s 2012/03/05 20:59:25 1.338.8.1
+++ src/sys/arch/sparc64/sparc64/locore.s 2012/03/21 16:10:21 1.338.8.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: locore.s,v 1.338.8.1 2012/03/05 20:59:25 sborrill Exp $ */ 1/* $NetBSD: locore.s,v 1.338.8.2 2012/03/21 16:10:21 riz Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2006-2010 Matthew R. Green 4 * Copyright (c) 2006-2010 Matthew R. Green
5 * Copyright (c) 1996-2002 Eduardo Horvath 5 * Copyright (c) 1996-2002 Eduardo Horvath
6 * Copyright (c) 1996 Paul Kranenburg 6 * Copyright (c) 1996 Paul Kranenburg
7 * Copyright (c) 1996 7 * Copyright (c) 1996
8 * The President and Fellows of Harvard College. 8 * The President and Fellows of Harvard College.
9 * All rights reserved. 9 * All rights reserved.
10 * Copyright (c) 1992, 1993 10 * Copyright (c) 1992, 1993
11 * The Regents of the University of California. 11 * The Regents of the University of California.
12 * All rights reserved. 12 * All rights reserved.
13 * 13 *
14 * This software was developed by the Computer Systems Engineering group 14 * This software was developed by the Computer Systems Engineering group
@@ -481,27 +481,27 @@ _C_LABEL(trapbase): @@ -481,27 +481,27 @@ _C_LABEL(trapbase):
481 HARDINT4U(9) ! 049 = level 9 interrupt 481 HARDINT4U(9) ! 049 = level 9 interrupt
482 HARDINT4U(10) ! 04a = level 10 interrupt 482 HARDINT4U(10) ! 04a = level 10 interrupt
483 HARDINT4U(11) ! 04b = level 11 interrupt 483 HARDINT4U(11) ! 04b = level 11 interrupt
484 ZS_INTERRUPT4U ! 04c = level 12 (zs) interrupt 484 ZS_INTERRUPT4U ! 04c = level 12 (zs) interrupt
485 HARDINT4U(13) ! 04d = level 13 interrupt 485 HARDINT4U(13) ! 04d = level 13 interrupt
486 HARDINT4U(14) ! 04e = level 14 interrupt 486 HARDINT4U(14) ! 04e = level 14 interrupt
487 HARDINT4U(15) ! 04f = nonmaskable interrupt 487 HARDINT4U(15) ! 04f = nonmaskable interrupt
488 UTRAP(0x050); UTRAP(0x051); UTRAP(0x052); UTRAP(0x053); UTRAP(0x054); UTRAP(0x055) 488 UTRAP(0x050); UTRAP(0x051); UTRAP(0x052); UTRAP(0x053); UTRAP(0x054); UTRAP(0x055)
489 UTRAP(0x056); UTRAP(0x057); UTRAP(0x058); UTRAP(0x059); UTRAP(0x05a); UTRAP(0x05b) 489 UTRAP(0x056); UTRAP(0x057); UTRAP(0x058); UTRAP(0x059); UTRAP(0x05a); UTRAP(0x05b)
490 UTRAP(0x05c); UTRAP(0x05d); UTRAP(0x05e); UTRAP(0x05f) 490 UTRAP(0x05c); UTRAP(0x05d); UTRAP(0x05e); UTRAP(0x05f)
491 VTRAP(0x060, interrupt_vector); ! 060 = interrupt vector 491 VTRAP(0x060, interrupt_vector); ! 060 = interrupt vector
492 TRAP(T_PA_WATCHPT) ! 061 = physical address data watchpoint 492 TRAP(T_PA_WATCHPT) ! 061 = physical address data watchpoint
493 TRAP(T_VA_WATCHPT) ! 062 = virtual address data watchpoint 493 TRAP(T_VA_WATCHPT) ! 062 = virtual address data watchpoint
494 UTRAP(T_ECCERR) ! We'll implement this one later 494 TRAP(T_ECCERR) ! 063 = corrected ECC error
495ufast_IMMU_miss: ! 064 = fast instr access MMU miss 495ufast_IMMU_miss: ! 064 = fast instr access MMU miss
496 ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer 496 ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer
497#ifdef NO_TSB 497#ifdef NO_TSB
498 ba,a %icc, instr_miss 498 ba,a %icc, instr_miss
499#endif 499#endif
500 ldxa [%g0] ASI_IMMU, %g1 ! Load IMMU tag target register 500 ldxa [%g0] ASI_IMMU, %g1 ! Load IMMU tag target register
501 ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4 ! Load TSB tag:data into %g4:%g5 501 ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4 ! Load TSB tag:data into %g4:%g5
502 brgez,pn %g5, instr_miss ! Entry invalid? Punt 502 brgez,pn %g5, instr_miss ! Entry invalid? Punt
503 cmp %g1, %g4 ! Compare TLB tags 503 cmp %g1, %g4 ! Compare TLB tags
504 bne,pn %xcc, instr_miss ! Got right tag? 504 bne,pn %xcc, instr_miss ! Got right tag?
505 nop 505 nop
506 CLRTT 506 CLRTT
507 stxa %g5, [%g0] ASI_IMMU_DATA_IN ! Enter new mapping 507 stxa %g5, [%g0] ASI_IMMU_DATA_IN ! Enter new mapping
@@ -717,27 +717,27 @@ kdatafault: @@ -717,27 +717,27 @@ kdatafault:
717 HARDINT4U(9) ! 049 = level 9 interrupt 717 HARDINT4U(9) ! 049 = level 9 interrupt
718 HARDINT4U(10) ! 04a = level 10 interrupt 718 HARDINT4U(10) ! 04a = level 10 interrupt
719 HARDINT4U(11) ! 04b = level 11 interrupt 719 HARDINT4U(11) ! 04b = level 11 interrupt
720 ZS_INTERRUPT4U ! 04c = level 12 (zs) interrupt 720 ZS_INTERRUPT4U ! 04c = level 12 (zs) interrupt
721 HARDINT4U(13) ! 04d = level 13 interrupt 721 HARDINT4U(13) ! 04d = level 13 interrupt
722 HARDINT4U(14) ! 04e = level 14 interrupt 722 HARDINT4U(14) ! 04e = level 14 interrupt
723 HARDINT4U(15) ! 04f = nonmaskable interrupt 723 HARDINT4U(15) ! 04f = nonmaskable interrupt
724 UTRAP(0x050); UTRAP(0x051); UTRAP(0x052); UTRAP(0x053); UTRAP(0x054); UTRAP(0x055) 724 UTRAP(0x050); UTRAP(0x051); UTRAP(0x052); UTRAP(0x053); UTRAP(0x054); UTRAP(0x055)
725 UTRAP(0x056); UTRAP(0x057); UTRAP(0x058); UTRAP(0x059); UTRAP(0x05a); UTRAP(0x05b) 725 UTRAP(0x056); UTRAP(0x057); UTRAP(0x058); UTRAP(0x059); UTRAP(0x05a); UTRAP(0x05b)
726 UTRAP(0x05c); UTRAP(0x05d); UTRAP(0x05e); UTRAP(0x05f) 726 UTRAP(0x05c); UTRAP(0x05d); UTRAP(0x05e); UTRAP(0x05f)
727 VTRAP(0x060, interrupt_vector); ! 060 = interrupt vector 727 VTRAP(0x060, interrupt_vector); ! 060 = interrupt vector
728 TRAP(T_PA_WATCHPT) ! 061 = physical address data watchpoint 728 TRAP(T_PA_WATCHPT) ! 061 = physical address data watchpoint
729 TRAP(T_VA_WATCHPT) ! 062 = virtual address data watchpoint 729 TRAP(T_VA_WATCHPT) ! 062 = virtual address data watchpoint
730 UTRAP(T_ECCERR) ! We'll implement this one later 730 TRAP(T_ECCERR) ! 063 = corrected ECC error
731kfast_IMMU_miss: ! 064 = fast instr access MMU miss 731kfast_IMMU_miss: ! 064 = fast instr access MMU miss
732 ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer 732 ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer
733#ifdef NO_TSB 733#ifdef NO_TSB
734 ba,a %icc, instr_miss 734 ba,a %icc, instr_miss
735#endif 735#endif
736 ldxa [%g0] ASI_IMMU, %g1 ! Load IMMU tag target register 736 ldxa [%g0] ASI_IMMU, %g1 ! Load IMMU tag target register
737 ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4 ! Load TSB tag:data into %g4:%g5 737 ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4 ! Load TSB tag:data into %g4:%g5
738 brgez,pn %g5, instr_miss ! Entry invalid? Punt 738 brgez,pn %g5, instr_miss ! Entry invalid? Punt
739 cmp %g1, %g4 ! Compare TLB tags 739 cmp %g1, %g4 ! Compare TLB tags
740 bne,pn %xcc, instr_miss ! Got right tag? 740 bne,pn %xcc, instr_miss ! Got right tag?
741 nop 741 nop
742 CLRTT 742 CLRTT
743 stxa %g5, [%g0] ASI_IMMU_DATA_IN ! Enter new mapping 743 stxa %g5, [%g0] ASI_IMMU_DATA_IN ! Enter new mapping

cvs diff -r1.168 -r1.168.8.1 src/sys/arch/sparc64/sparc64/trap.c (expand / switch to unified diff)

--- src/sys/arch/sparc64/sparc64/trap.c 2011/07/30 19:29:12 1.168
+++ src/sys/arch/sparc64/sparc64/trap.c 2012/03/21 16:10:21 1.168.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: trap.c,v 1.168 2011/07/30 19:29:12 martin Exp $ */ 1/* $NetBSD: trap.c,v 1.168.8.1 2012/03/21 16:10:21 riz Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved. 4 * Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
5 * Copyright (c) 1996 5 * Copyright (c) 1996
6 * The President and Fellows of Harvard College. All rights reserved. 6 * The President and Fellows of Harvard College. All rights reserved.
7 * Copyright (c) 1992, 1993 7 * Copyright (c) 1992, 1993
8 * The Regents of the University of California. All rights reserved. 8 * The Regents of the University of California. All rights reserved.
9 * 9 *
10 * This software was developed by the Computer Systems Engineering group 10 * This software was developed by the Computer Systems Engineering group
11 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 11 * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
12 * contributed to Berkeley. 12 * contributed to Berkeley.
13 * 13 *
14 * All advertising materials mentioning features or use of this software 14 * All advertising materials mentioning features or use of this software
@@ -40,27 +40,27 @@ @@ -40,27 +40,27 @@
40 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 40 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE. 47 * SUCH DAMAGE.
48 * 48 *
49 * @(#)trap.c 8.4 (Berkeley) 9/23/93 49 * @(#)trap.c 8.4 (Berkeley) 9/23/93
50 */ 50 */
51 51
52#include <sys/cdefs.h> 52#include <sys/cdefs.h>
53__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.168 2011/07/30 19:29:12 martin Exp $"); 53__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.168.8.1 2012/03/21 16:10:21 riz Exp $");
54 54
55#include "opt_ddb.h" 55#include "opt_ddb.h"
56#include "opt_multiprocessor.h" 56#include "opt_multiprocessor.h"
57#include "opt_compat_svr4.h" 57#include "opt_compat_svr4.h"
58#include "opt_compat_netbsd32.h" 58#include "opt_compat_netbsd32.h"
59 59
60#include <sys/param.h> 60#include <sys/param.h>
61#include <sys/systm.h> 61#include <sys/systm.h>
62#include <sys/pool.h> 62#include <sys/pool.h>
63#include <sys/proc.h> 63#include <sys/proc.h>
64#include <sys/ras.h> 64#include <sys/ras.h>
65#include <sys/sa.h> 65#include <sys/sa.h>
66#include <sys/savar.h> 66#include <sys/savar.h>
@@ -84,26 +84,28 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.1 @@ -84,26 +84,28 @@ __KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.1
84 84
85#ifdef DDB 85#ifdef DDB
86#include <machine/db_machdep.h> 86#include <machine/db_machdep.h>
87#else 87#else
88#include <machine/frame.h> 88#include <machine/frame.h>
89#endif 89#endif
90#ifdef COMPAT_SVR4 90#ifdef COMPAT_SVR4
91#include <machine/svr4_machdep.h> 91#include <machine/svr4_machdep.h>
92#endif 92#endif
93#ifdef COMPAT_SVR4_32 93#ifdef COMPAT_SVR4_32
94#include <machine/svr4_32_machdep.h> 94#include <machine/svr4_32_machdep.h>
95#endif 95#endif
96 96
 97#include <sparc64/sparc64/cache.h>
 98
97#include <sparc/fpu/fpu_extern.h> 99#include <sparc/fpu/fpu_extern.h>
98 100
99#ifndef offsetof 101#ifndef offsetof
100#define offsetof(s, f) ((size_t)&((s *)0)->f) 102#define offsetof(s, f) ((size_t)&((s *)0)->f)
101#endif 103#endif
102 104
103#ifdef TRAPSTATS 105#ifdef TRAPSTATS
104/* trapstats */ 106/* trapstats */
105int protfix = 0; 107int protfix = 0;
106int udmiss = 0; /* Number of normal/nucleus data/text miss/protection faults */ 108int udmiss = 0; /* Number of normal/nucleus data/text miss/protection faults */
107int udhit = 0;  109int udhit = 0;
108int udprot = 0; 110int udprot = 0;
109int utmiss = 0; 111int utmiss = 0;
@@ -149,26 +151,30 @@ int trapdebug = 0/*|TDB_SYSCALL|TDB_STOP @@ -149,26 +151,30 @@ int trapdebug = 0/*|TDB_SYSCALL|TDB_STOP
149#endif 151#endif
150 152
151#ifdef DDB 153#ifdef DDB
152#if 1 154#if 1
153#define DEBUGGER(t,f) do { kdb_trap(t,f); } while (0) 155#define DEBUGGER(t,f) do { kdb_trap(t,f); } while (0)
154#else 156#else
155#define DEBUGGER(t,f) Debugger() 157#define DEBUGGER(t,f) Debugger()
156#endif 158#endif
157#else 159#else
158#define DEBUGGER(t,f) 160#define DEBUGGER(t,f)
159#define Debugger() 161#define Debugger()
160#endif 162#endif
161 163
 164struct evcnt ecc_corrected =
 165 EVCNT_INITIALIZER(EVCNT_TYPE_MISC,0,"ECC","corrected");
 166EVCNT_ATTACH_STATIC(ecc_corrected);
 167
162/* 168/*
163 * Initial FPU state is all registers == all 1s, everything else == all 0s. 169 * Initial FPU state is all registers == all 1s, everything else == all 0s.
164 * This makes every floating point register a signalling NaN, with sign bit 170 * This makes every floating point register a signalling NaN, with sign bit
165 * set, no matter how it is interpreted. Appendix N of the Sparc V8 document 171 * set, no matter how it is interpreted. Appendix N of the Sparc V8 document
166 * seems to imply that we should do this, and it does make sense. 172 * seems to imply that we should do this, and it does make sense.
167 */ 173 */
168const struct fpstate64 initfpstate __aligned(SPARC64_BLOCK_SIZE) = { 174const struct fpstate64 initfpstate __aligned(SPARC64_BLOCK_SIZE) = {
169 .fs_regs = 175 .fs_regs =
170 { ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 176 { ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
171 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 177 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
172 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, 178 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0,
173 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0 }, 179 ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0, ~0 },
174 .fs_qsize = 0 180 .fs_qsize = 0
@@ -361,26 +367,27 @@ const char *trap_type[] = { @@ -361,26 +367,27 @@ const char *trap_type[] = {
361}; 367};
362 368
363#define N_TRAP_TYPES (sizeof trap_type / sizeof *trap_type) 369#define N_TRAP_TYPES (sizeof trap_type / sizeof *trap_type)
364 370
365void trap(struct trapframe64 *, unsigned int, vaddr_t, long); 371void trap(struct trapframe64 *, unsigned int, vaddr_t, long);
366void data_access_fault(struct trapframe64 *, unsigned int, vaddr_t, vaddr_t, 372void data_access_fault(struct trapframe64 *, unsigned int, vaddr_t, vaddr_t,
367 vaddr_t, u_long); 373 vaddr_t, u_long);
368void data_access_error(struct trapframe64 *, unsigned int, vaddr_t, u_long, 374void data_access_error(struct trapframe64 *, unsigned int, vaddr_t, u_long,
369 vaddr_t, u_long); 375 vaddr_t, u_long);
370void text_access_fault(struct trapframe64 *tf, unsigned int type, vaddr_t pc, 376void text_access_fault(struct trapframe64 *tf, unsigned int type, vaddr_t pc,
371 u_long sfsr); 377 u_long sfsr);
372void text_access_error(struct trapframe64 *, unsigned int, vaddr_t, u_long, 378void text_access_error(struct trapframe64 *, unsigned int, vaddr_t, u_long,
373 vaddr_t, u_long); 379 vaddr_t, u_long);
 380void ecc_corrected_error(unsigned int type, vaddr_t pc);
374 381
375#ifdef DEBUG 382#ifdef DEBUG
376void print_trapframe(struct trapframe64 *); 383void print_trapframe(struct trapframe64 *);
377 384
378void 385void
379print_trapframe(struct trapframe64 *tf) 386print_trapframe(struct trapframe64 *tf)
380{ 387{
381 388
382 printf("Trapframe %p:\ttstate: %lx\tpc: %lx\tnpc: %lx\n", 389 printf("Trapframe %p:\ttstate: %lx\tpc: %lx\tnpc: %lx\n",
383 tf, (u_long)tf->tf_tstate, (u_long)tf->tf_pc, (u_long)tf->tf_npc); 390 tf, (u_long)tf->tf_tstate, (u_long)tf->tf_pc, (u_long)tf->tf_npc);
384 printf("fault: %p\ty: %x\t",  391 printf("fault: %p\ty: %x\t",
385 (void *)(u_long)tf->tf_fault, (int)tf->tf_y); 392 (void *)(u_long)tf->tf_fault, (int)tf->tf_y);
386 printf("pil: %d\toldpil: %d\ttt: %x\tGlobals:\n",  393 printf("pil: %d\toldpil: %d\ttt: %x\tGlobals:\n",
@@ -530,26 +537,29 @@ trap(struct trapframe64 *tf, unsigned in @@ -530,26 +537,29 @@ trap(struct trapframe64 *tf, unsigned in
530 fplwp = NULL; 537 fplwp = NULL;
531 } 538 }
532 rstintr(); 539 rstintr();
533 /* If we have an allocated fpstate, load it */ 540 /* If we have an allocated fpstate, load it */
534 if (newfplwp->l_md.md_fpstate != NULL) { 541 if (newfplwp->l_md.md_fpstate != NULL) {
535 fplwp = newfplwp; 542 fplwp = newfplwp;
536 loadfpstate(fplwp->l_md.md_fpstate); 543 loadfpstate(fplwp->l_md.md_fpstate);
537 } else 544 } else
538 fplwp = NULL; 545 fplwp = NULL;
539 } 546 }
540 /* Enable the FPU */ 547 /* Enable the FPU */
541 tf->tf_tstate |= TSTATE_PEF; 548 tf->tf_tstate |= TSTATE_PEF;
542 return; 549 return;
 550 } else if (type == T_ECCERR) {
 551 ecc_corrected_error(type, pc);
 552 return;
543 } 553 }
544 goto dopanic; 554 goto dopanic;
545 } 555 }
546 l = curlwp; 556 l = curlwp;
547 p = l->l_proc; 557 p = l->l_proc;
548 LWP_CACHE_CREDS(l, p); 558 LWP_CACHE_CREDS(l, p);
549 sticks = p->p_sticks; 559 sticks = p->p_sticks;
550 pcb = lwp_getpcb(l); 560 pcb = lwp_getpcb(l);
551 l->l_md.md_tf = tf; /* for ptrace/signals */ 561 l->l_md.md_tf = tf; /* for ptrace/signals */
552 562
553 sig = 0; 563 sig = 0;
554 564
555 switch (type) { 565 switch (type) {
@@ -845,26 +855,29 @@ badtrap: @@ -845,26 +855,29 @@ badtrap:
845 l->l_proc->p_md.md_flags |= MDP_FIXALIGN; 855 l->l_proc->p_md.md_flags |= MDP_FIXALIGN;
846 ADVANCE; 856 ADVANCE;
847 break; 857 break;
848 858
849 case T_INTOF: 859 case T_INTOF:
850 uprintf("T_INTOF\n"); /* XXX */ 860 uprintf("T_INTOF\n"); /* XXX */
851 ADVANCE; 861 ADVANCE;
852 sig = SIGFPE; 862 sig = SIGFPE;
853 KSI_INIT_TRAP(&ksi); 863 KSI_INIT_TRAP(&ksi);
854 ksi.ksi_trap = type; 864 ksi.ksi_trap = type;
855 ksi.ksi_code = FPE_INTOVF; 865 ksi.ksi_code = FPE_INTOVF;
856 ksi.ksi_addr = (void *)pc; 866 ksi.ksi_addr = (void *)pc;
857 break; 867 break;
 868 case T_ECCERR:
 869 ecc_corrected_error(type, pc);
 870 break;
858 } 871 }
859 if (sig != 0) { 872 if (sig != 0) {
860 ksi.ksi_signo = sig; 873 ksi.ksi_signo = sig;
861 trapsignal(l, &ksi); 874 trapsignal(l, &ksi);
862 } 875 }
863 userret(l, pc, sticks); 876 userret(l, pc, sticks);
864 share_fpu(l, tf); 877 share_fpu(l, tf);
865#undef ADVANCE 878#undef ADVANCE
866#ifdef DEBUG 879#ifdef DEBUG
867 if (trapdebug & (TDB_FOLLOW | TDB_TRAP)) { 880 if (trapdebug & (TDB_FOLLOW | TDB_TRAP)) {
868 printf("trap: done\n"); 881 printf("trap: done\n");
869 /* if (type != T_BREAKPOINT) Debugger(); */ 882 /* if (type != T_BREAKPOINT) Debugger(); */
870 } 883 }
@@ -1612,13 +1625,58 @@ text_access_error(struct trapframe64 *tf @@ -1612,13 +1625,58 @@ text_access_error(struct trapframe64 *tf
1612out: 1625out:
1613 if ((tstate & TSTATE_PRIV) == 0) { 1626 if ((tstate & TSTATE_PRIV) == 0) {
1614 userret(l, pc, sticks); 1627 userret(l, pc, sticks);
1615 share_fpu(l, tf); 1628 share_fpu(l, tf);
1616 } 1629 }
1617#ifdef DEBUG 1630#ifdef DEBUG
1618 if (trapdebug & (TDB_TXTFLT | TDB_FOLLOW)) 1631 if (trapdebug & (TDB_TXTFLT | TDB_FOLLOW))
1619 printf("text_access_error: done\n"); 1632 printf("text_access_error: done\n");
1620 if (trapdebug & TDB_FRAME) { 1633 if (trapdebug & TDB_FRAME) {
1621 print_trapframe(tf); 1634 print_trapframe(tf);
1622 } 1635 }
1623#endif 1636#endif
1624} 1637}
 1638
 1639/*
 1640 * Handle an ECC corrected event.
 1641 */
 1642void
 1643ecc_corrected_error(unsigned int type, vaddr_t pc)
 1644{
 1645 uint64_t eeer, afar, afsr;
 1646 char buf[128];
 1647 int s;
 1648
 1649 /* Clear the error */
 1650 eeer = ldxa(0, ASI_ERROR_EN_REG);
 1651 s = intr_disable();
 1652 stxa(0, ASI_ERROR_EN_REG,
 1653 eeer & ~(P_EER_NCEEN | P_EER_CEEN));
 1654 membar_Sync();
 1655 intr_restore(s);
 1656
 1657 /* Flush the caches in order ensure no corrupt data got installed. */
 1658 blast_dcache();
 1659 blast_icache();
 1660
 1661#if 0
 1662 /* Ensure the caches are still turned on (should be). */
 1663 cache_enable(PCPU_GET(impl));
 1664#endif
 1665
 1666 /* Grab the current AFSR/AFAR, and clear the error from the AFSR. */
 1667 afar = ldxa(0, ASI_AFAR);
 1668 afsr = ldxa(0, ASI_AFSR);
 1669 s = intr_disable();
 1670 stxa(0, ASI_AFSR, ldxa(0, ASI_AFSR));
 1671 membar_Sync();
 1672 intr_restore(s);
 1673 ecc_corrected.ev_count++;
 1674 snprintb(buf, sizeof(buf), AFSR_BITS, afsr);
 1675 printf("corrected ECC error: pc %p afsr %"PRIx64" (%s) addr %"PRIx64"\n", (void *)pc, afsr, buf, afar);
 1676
 1677 /* Turn (non-)correctable error reporting back on. */
 1678 s = intr_disable();
 1679 stxa(0, ASI_ERROR_EN_REG, eeer);
 1680 membar_Sync();
 1681 intr_restore(s);
 1682}