diff options
-rw-r--r-- | sys/arch/sparc64/include/cpu.h | 10 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/locore.s | 60 | ||||
-rw-r--r-- | sys/arch/sparc64/sparc64/machdep.c | 9 |
3 files changed, 72 insertions, 7 deletions
diff --git a/sys/arch/sparc64/include/cpu.h b/sys/arch/sparc64/include/cpu.h index 24dacd82711..2f7a606964b 100644 --- a/sys/arch/sparc64/include/cpu.h +++ b/sys/arch/sparc64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.18 2003/03/20 23:05:30 henric Exp $ */ +/* $OpenBSD: cpu.h,v 1.19 2003/03/21 22:59:09 jason Exp $ */ /* $NetBSD: cpu.h,v 1.28 2001/06/14 22:56:58 thorpej Exp $ */ /* @@ -54,8 +54,10 @@ #define CPU_BOOTED_KERNEL 1 /* string: booted kernel name */ #define CPU_LED_BLINK 2 /* int: blink leds? */ #define CPU_ALLOWAPERTURE 3 /* allow xf86 operations */ -#define CPU_CPUTYPE 4 /* cpu type */ -#define CPU_MAXID 5 /* number of valid machdep ids */ +#define CPU_CPUTYPE 4 /* cpu type */ +#define CPU_CECCERRORS 5 /* Correctable ECC errors */ +#define CPU_CECCLAST 6 /* Correctable ECC last fault addr */ +#define CPU_MAXID 7 /* number of valid machdep ids */ #define CTL_MACHDEP_NAMES { \ { 0, 0 }, \ @@ -63,6 +65,8 @@ { "led_blink", CTLTYPE_INT }, \ { "allowaperture", CTLTYPE_INT }, \ { "cputype", CTLTYPE_INT }, \ + { "ceccerrs", CTLTYPE_INT }, \ + { "cecclast", CTLTYPE_QUAD }, \ } #ifdef _KERNEL diff --git a/sys/arch/sparc64/sparc64/locore.s b/sys/arch/sparc64/sparc64/locore.s index cee315361d6..c6d5c5f8a6e 100644 --- a/sys/arch/sparc64/sparc64/locore.s +++ b/sys/arch/sparc64/sparc64/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.30 2003/03/20 23:05:30 henric Exp $ */ +/* $OpenBSD: locore.s,v 1.31 2003/03/21 22:59:10 jason Exp $ */ /* $NetBSD: locore.s,v 1.137 2001/08/13 06:10:10 jdolecek Exp $ */ /* @@ -847,7 +847,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 + VTRAP(T_ECCERR, cecc_catch) ! 063 = Correctable ECC error ufast_IMMU_miss: ! 064 = fast instr access MMU miss TRACEFLT ! DEBUG ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer @@ -1083,7 +1083,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 + VTRAP(T_ECCERR, cecc_catch) ! 063 = Correctable ECC error kfast_IMMU_miss: ! 064 = fast instr access MMU miss TRACEFLT ! DEBUG ldxa [%g0] ASI_IMMU_8KPTR, %g2 ! Load IMMU 8K TSB pointer @@ -11476,6 +11476,60 @@ ENTRY(loadfpstate) ta 1 retl nop + +/* XXX belongs elsewhere (ctlreg.h?) */ +#define AFSR_CECC_ERROR 0x100000 /* AFSR Correctable ECC err */ +#define DATAPATH_CE 0x100 /* Datapath Correctable Err */ + + .data + _ALIGN + .globl _C_LABEL(cecclast), _C_LABEL(ceccerrs) +_C_LABEL(cecclast): + .xword 0 +_C_LABEL(ceccerrs): + .word 0 + _ALIGN + .text + +/* + * ECC Correctable Error handler - this doesn't do much except intercept + * the error and reset the status bits. + */ +ENTRY(cecc_catch) + ldxa [%g0] ASI_AFSR, %g1 ! g1 = AFSR + ldxa [%g0] ASI_AFAR, %g2 ! g2 = AFAR + + sethi %hi(cecclast), %g1 ! cecclast = AFAR + or %g1, %lo(cecclast), %g1 + stx %g2, [%g1] + + sethi %hi(ceccerrs), %g1 ! get current count + or %g1, %lo(ceccerrs), %g1 + lduw [%g1], %g2 ! g2 = ceccerrs + + ldxa [%g0] ASI_DATAPATH_ERR_REG_READ, %g3 ! Read UDB-Low status + andcc %g3, DATAPATH_CE, %g4 ! Check CE bit + be,pn %xcc, 1f ! Don't clear unless + nop ! necessary + stxa %g4, [%g0] ASI_DATAPATH_ERR_REG_WRITE ! Clear CE bit in UDBL + membar #Sync ! sync store + inc %g2 ! ceccerrs++ +1: mov 0x18, %g5 + ldxa [%g5] ASI_DATAPATH_ERR_REG_READ, %g3 ! Read UDB-High status + andcc %g3, DATAPATH_CE, %g4 ! Check CE bit + be,pn %xcc, 1f ! Don't clear unless + nop ! necessary + stxa %g4, [%g5] ASI_DATAPATH_ERR_REG_WRITE ! Clear CE bit in UDBH + membar #Sync ! sync store + inc %g2 ! ceccerrs++ +1: set AFSR_CECC_ERROR, %g3 + stxa %g3, [%g0] ASI_AFSR ! Clear CE in AFSR + stw %g2, [%g1] ! set ceccerrs + membar #Sync ! sync store + CLRTT + retry + NOTREACHED + /* * ienab_bis(bis) int bis; * ienab_bic(bic) int bic; diff --git a/sys/arch/sparc64/sparc64/machdep.c b/sys/arch/sparc64/sparc64/machdep.c index 4a558e50c9b..fe8ce73f892 100644 --- a/sys/arch/sparc64/sparc64/machdep.c +++ b/sys/arch/sparc64/sparc64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.58 2003/03/06 08:26:08 henric Exp $ */ +/* $OpenBSD: machdep.c,v 1.59 2003/03/21 22:59:10 jason Exp $ */ /* $NetBSD: machdep.c,v 1.108 2001/07/24 19:30:14 eeh Exp $ */ /*- @@ -212,6 +212,9 @@ int allowaperture = 0; #endif #endif +extern int ceccerrs; +extern int64_t cecclast; + /* * Maximum number of DMA segments we'll allow in dmamem_load() * routines. Can be overridden in config files, etc. @@ -574,6 +577,10 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) #endif case CPU_CPUTYPE: return (sysctl_rdint(oldp, oldlenp, newp, CPU_SUN4U)); + case CPU_CECCERRORS: + return (sysctl_rdint(oldp, oldlenp, newp, ceccerrs)); + case CPU_CECCLAST: + return (sysctl_rdquad(oldp, oldlenp, newp, cecclast)); default: return (EOPNOTSUPP); } |