summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sparc64/include/cpu.h10
-rw-r--r--sys/arch/sparc64/sparc64/locore.s60
-rw-r--r--sys/arch/sparc64/sparc64/machdep.c9
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);
}