summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormiod <miod@openbsd.org>2014-11-22 22:48:38 +0000
committermiod <miod@openbsd.org>2014-11-22 22:48:38 +0000
commitfebcf9eec4b1065eefb2597eb953e37d30caf79e (patch)
tree618c64a034f9cafe95400fcbda4b69d5cc0f3986
parentPrevious diff changed the location of the ACPI S3/S4 trampoline, which has (diff)
downloadwireguard-openbsd-febcf9eec4b1065eefb2597eb953e37d30caf79e.tar.xz
wireguard-openbsd-febcf9eec4b1065eefb2597eb953e37d30caf79e.zip
Driver for the ECC memory controller found on some sun4m (ss20), so that
recoverable memory errors no longer panic the kernel. From NetBSD but the manual page.
-rw-r--r--share/man/man4/man4.sparc/Makefile25
-rw-r--r--share/man/man4/man4.sparc/eccmemctl.435
-rw-r--r--sys/arch/sparc/conf/GENERIC5
-rw-r--r--sys/arch/sparc/conf/RAMDISK4
-rw-r--r--sys/arch/sparc/conf/SUN4M5
-rw-r--r--sys/arch/sparc/conf/files.sparc6
-rw-r--r--sys/arch/sparc/sparc/autoconf.c3
-rw-r--r--sys/arch/sparc/sparc/intr.c13
-rw-r--r--sys/arch/sparc/sparc/memecc.c132
-rw-r--r--sys/arch/sparc/sparc/memeccreg.h83
10 files changed, 294 insertions, 17 deletions
diff --git a/share/man/man4/man4.sparc/Makefile b/share/man/man4/man4.sparc/Makefile
index 7534f5f17ef..c33cf8b9067 100644
--- a/share/man/man4/man4.sparc/Makefile
+++ b/share/man/man4/man4.sparc/Makefile
@@ -1,12 +1,25 @@
-# $OpenBSD: Makefile,v 1.43 2009/05/20 18:22:32 miod Exp $
+# $OpenBSD: Makefile,v 1.44 2014/11/22 22:48:38 miod Exp $
# from: @(#)Makefile 8.2 (Berkeley) 2/16/94
-MAN= agten.4 audioamd.4 audiocs.4 autoconf.4 auxreg.4 be.4 bpp.4 bwtwo.4 \
+MAN= agten.4 audioamd.4 audiocs.4 autoconf.4 auxreg.4 \
+ be.4 bpp.4 bwtwo.4 \
cgtwo.4 cgthree.4 cgfour.4 cgsix.4 cgeight.4 cgtwelve.4 cgfourteen.4 \
- clock.4 daadio.4 esp.4 fga.4 ie.4 intro.4 le.4 led.4 magma.4 \
- mem.4 mgx.4 openprom.4 pninek.4 pnozz.4 presto.4 qe.4 qec.4 rfx.4 \
- scf.4 si.4 spif.4 sw.4 tctrl.4 tcx.4 timer.4 tslot.4 tvtwo.4 vigra.4 \
- xbox.4 xd.4 xy.4 zs.4 zx.4
+ clock.4 \
+ daadio.4 \
+ eccmemctl.4 esp.4 \
+ fga.4 \
+ ie.4 intro.4 \
+ le.4 led.4 \
+ magma.4 mem.4 mgx.4 \
+ openprom.4 \
+ pninek.4 pnozz.4 presto.4 \
+ qe.4 qec.4 \
+ rfx.4 \
+ scf.4 si.4 spif.4 sw.4 \
+ tctrl.4 tcx.4 timer.4 tslot.4 tvtwo.4 \
+ vigra.4 \
+ xbox.4 xd.4 xy.4 \
+ zs.4 zx.4
MLINKS= clock.4 oclock.4 \
fga.4 fvme.4 \
le.4 lebuffer.4 le.4 ledma.4 \
diff --git a/share/man/man4/man4.sparc/eccmemctl.4 b/share/man/man4/man4.sparc/eccmemctl.4
new file mode 100644
index 00000000000..c27a42f1c0a
--- /dev/null
+++ b/share/man/man4/man4.sparc/eccmemctl.4
@@ -0,0 +1,35 @@
+.\" $OpenBSD: eccmemctl.4,v 1.1 2014/11/22 22:48:38 miod Exp $
+.\"
+.\" Copyright (c) 2014, Miodrag Vallat.
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: November 22 2014 $
+.Dt ECCMEMCTL 4 sparc
+.Os
+.Sh NAME
+.Nm eccmemctl
+.Nd ECC memory controller
+.Sh SYNOPSIS
+.Cd "eccmemctl0 at mainbus0 " Pq "sun4m"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the ECC memory controller found on some
+sun4m systems.
+It will enable ECC memory checking, and will report detailed information about
+memory errors occuring.
+.Sh SEE ALSO
+.Xr intro 4 ,
+.Xr mainbus 4
+.\" .Xr memreg 4
diff --git a/sys/arch/sparc/conf/GENERIC b/sys/arch/sparc/conf/GENERIC
index 29a8da7cc0e..43e1d2c39c9 100644
--- a/sys/arch/sparc/conf/GENERIC
+++ b/sys/arch/sparc/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.106 2014/10/25 16:51:31 miod Exp $
+# $OpenBSD: GENERIC,v 1.107 2014/11/22 22:48:38 miod Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -73,6 +73,9 @@ memreg0 at mainbus0 # sun4c and sun4e
memreg0 at obio0 # sun4m
memreg0 at obio0 addr 0xf4000000 # sun4
+# ECC memory control
+eccmemctl0 at mainbus0 # sun4m
+
# Timer chip found on 4/300, sun4c, and sun4m systems.
timer0 at mainbus0 # sun4c and sun4e
timer0 at obio0 # sun4m
diff --git a/sys/arch/sparc/conf/RAMDISK b/sys/arch/sparc/conf/RAMDISK
index fbababc9c01..d5a45031783 100644
--- a/sys/arch/sparc/conf/RAMDISK
+++ b/sys/arch/sparc/conf/RAMDISK
@@ -1,4 +1,4 @@
-# $OpenBSD: RAMDISK,v 1.76 2014/10/10 05:43:35 deraadt Exp $
+# $OpenBSD: RAMDISK,v 1.77 2014/11/22 22:48:38 miod Exp $
machine sparc
maxusers 4
@@ -51,6 +51,8 @@ memreg0 at mainbus0 # sun4c and sun4e
memreg0 at obio0 # sun4m
memreg0 at obio0 addr 0xf4000000 # sun4
+eccmemctl0 at mainbus0 # sun4m
+
timer0 at mainbus0 # sun4c and sun4e
timer0 at obio0 # sun4m
timer0 at obio0 addr 0xef000000 # sun4/300
diff --git a/sys/arch/sparc/conf/SUN4M b/sys/arch/sparc/conf/SUN4M
index a6ab372c2e8..8bed40f996d 100644
--- a/sys/arch/sparc/conf/SUN4M
+++ b/sys/arch/sparc/conf/SUN4M
@@ -1,4 +1,4 @@
-# $OpenBSD: SUN4M,v 1.83 2014/10/25 16:51:31 miod Exp $
+# $OpenBSD: SUN4M,v 1.84 2014/11/22 22:48:38 miod Exp $
# $NetBSD: GENERIC,v 1.28.2.1 1996/07/02 23:55:22 jtc Exp $
# Machine architecture; required by config(8)
@@ -52,6 +52,9 @@ clock0 at obio0 # sun4m
# Memory error registers.
memreg0 at obio0 # sun4m
+# ECC memory control
+eccmemctl0 at mainbus0 # sun4m
+
# Timer chip found on 4/300, sun4c, and sun4m systems.
timer0 at obio0 # sun4m
diff --git a/sys/arch/sparc/conf/files.sparc b/sys/arch/sparc/conf/files.sparc
index a676ec48e6b..36470b78ed8 100644
--- a/sys/arch/sparc/conf/files.sparc
+++ b/sys/arch/sparc/conf/files.sparc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.sparc,v 1.96 2014/10/12 19:21:41 miod Exp $
+# $OpenBSD: files.sparc,v 1.97 2014/11/22 22:48:38 miod Exp $
# $NetBSD: files.sparc,v 1.44 1997/08/31 21:29:16 pk Exp $
# @(#)files.sparc 8.1 (Berkeley) 7/19/93
@@ -61,6 +61,10 @@ device memreg
attach memreg at mainbus, obio
file arch/sparc/sparc/memreg.c
+device eccmemctl
+attach eccmemctl at mainbus
+file arch/sparc/sparc/memecc.c eccmemctl
+
device zs {[channel = -1]}
attach zs at mainbus, obio
file arch/sparc/dev/zs.c zs needs-flag
diff --git a/sys/arch/sparc/sparc/autoconf.c b/sys/arch/sparc/sparc/autoconf.c
index bb338bf3e7c..766bfcb3eb1 100644
--- a/sys/arch/sparc/sparc/autoconf.c
+++ b/sys/arch/sparc/sparc/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.96 2014/11/16 12:30:58 deraadt Exp $ */
+/* $OpenBSD: autoconf.c,v 1.97 2014/11/22 22:48:38 miod Exp $ */
/* $NetBSD: autoconf.c,v 1.73 1997/07/29 09:41:53 fair Exp $ */
/*
@@ -1163,7 +1163,6 @@ mainbus_attach(parent, dev, aux)
* elsewhere.
*/
"SUNW,sx", /* XXX: no driver for SX yet */
- "eccmemctl",
"virtual-memory",
"aliases",
"memory",
diff --git a/sys/arch/sparc/sparc/intr.c b/sys/arch/sparc/sparc/intr.c
index d06cdc9d71b..de042ed21c8 100644
--- a/sys/arch/sparc/sparc/intr.c
+++ b/sys/arch/sparc/sparc/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.39 2014/07/12 18:44:43 tedu Exp $ */
+/* $OpenBSD: intr.c,v 1.40 2014/11/22 22:48:38 miod Exp $ */
/* $NetBSD: intr.c,v 1.20 1997/07/29 09:42:03 fair Exp $ */
/*
@@ -92,15 +92,16 @@ strayintr(fp)
#if defined(SUN4M)
void nmi_hard(void);
+
+int (*memerr_handler)(void);
+
void
nmi_hard()
{
/*
* A level 15 hard interrupt.
*/
-#ifdef noyet
int fatal = 0;
-#endif
u_int32_t si;
u_int afsr, afva;
@@ -125,12 +126,12 @@ nmi_hard()
si = *((u_int32_t *)ICR_SI_PEND);
printf("NMI: system interrupts: %b\n", si, SINTR_BITS);
-#ifdef notyet
if ((si & SINTR_M) != 0) {
/* ECC memory error */
if (memerr_handler != NULL)
fatal |= (*memerr_handler)();
}
+#ifdef notyet
if ((si & SINTR_I) != 0) {
/* MBus/SBus async error */
if (sbuserr_handler != NULL)
@@ -146,9 +147,11 @@ nmi_hard()
if (moduleerr_handler != NULL)
fatal |= (*moduleerr_handler)();
}
+#else
+ fatal |= si & (SINTR_I | SINTR_V | SINTR_ME);
+#endif
if (fatal)
-#endif
panic("nmi");
}
#endif
diff --git a/sys/arch/sparc/sparc/memecc.c b/sys/arch/sparc/sparc/memecc.c
new file mode 100644
index 00000000000..3512dc5e38a
--- /dev/null
+++ b/sys/arch/sparc/sparc/memecc.c
@@ -0,0 +1,132 @@
+/* $OpenBSD: memecc.c,v 1.1 2014/11/22 22:48:38 miod Exp $ */
+/* $NetBSD: memecc.c,v 1.16 2013/10/19 19:40:23 mrg Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ECC memory control.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/autoconf.h>
+#include <sparc/sparc/memeccreg.h>
+
+struct memecc_softc {
+ struct device sc_dev;
+ vaddr_t sc_reg;
+};
+
+struct memecc_softc *memecc_sc;
+
+/* autoconfiguration driver */
+void memecc_attach(struct device *, struct device *, void *);
+int memecc_match(struct device *, void *, void *);
+int memecc_error(void);
+
+extern int (*memerr_handler)(void);
+
+const struct cfattach eccmemctl_ca = {
+ sizeof(struct memecc_softc),
+ memecc_match,
+ memecc_attach
+};
+
+struct cfdriver eccmemctl_cd = {
+ 0, "eccmemctl", DV_DULL
+};
+
+int
+memecc_match(struct device *parent, void *vcf, void *aux)
+{
+ struct confargs *ca = aux;
+
+ if (memerr_handler != NULL)
+ return 0;
+
+ return (strcmp("eccmemctl", ca->ca_ra.ra_name) == 0);
+}
+
+/*
+ * Attach the device.
+ */
+void
+memecc_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct memecc_softc *sc = (struct memecc_softc *)self;
+ struct confargs *ca = aux;
+ struct romaux *ra = &ca->ca_ra;
+ uint32_t reg;
+
+ /* XXX getprop width, mc-type */
+ sc->sc_reg = ra->ra_vaddr != NULL ? (vaddr_t)ra->ra_vaddr :
+ (vaddr_t)mapiodev(ra->ra_reg, 0, 0x20);
+
+ reg = *(volatile uint32_t *)(sc->sc_reg + ECC_EN_REG);
+
+ printf(": version 0x%x/0x%x\n",
+ (reg & ECC_EN_VER) >> 24,
+ (reg & ECC_EN_IMPL) >> 28);
+
+ /* Enable checking & interrupts */
+ reg |= ECC_EN_EE | ECC_EN_EI;
+ *(volatile uint32_t *)(sc->sc_reg + ECC_EN_REG) = reg;
+ memecc_sc = sc;
+
+ memerr_handler = memecc_error;
+}
+
+/*
+ * Called if the MEMORY ERROR bit is set after a level 25 interrupt.
+ */
+int
+memecc_error(void)
+{
+ uint32_t efsr, efar0, efar1;
+
+ efsr = *(volatile uint32_t *)(memecc_sc->sc_reg + ECC_FSR_REG);
+ efar0 = *(volatile uint32_t *)(memecc_sc->sc_reg + ECC_AFR0_REG);
+ efar1 = *(volatile uint32_t *)(memecc_sc->sc_reg + ECC_AFR1_REG);
+ printf("memory error:\n\tEFSR: %08x\n", efsr);
+ printf("\tMBus transaction: %08x\n", efar0 & ~ECC_AFR_PAH);
+ printf("\taddress: 0x%x%x\n", efar0 & ECC_AFR_PAH, efar1);
+#if 0
+ printf("\tmodule location: %s\n",
+ prom_pa_location(efar1, efar0 & ECC_AFR_PAH));
+#endif
+
+ /* Unlock registers and clear interrupt */
+ *(volatile uint32_t *)(memecc_sc->sc_reg + ECC_FSR_REG) = efsr;
+
+ /* Return 0 if this was a correctable error */
+ return ((efsr & ECC_FSR_CE) == 0);
+}
diff --git a/sys/arch/sparc/sparc/memeccreg.h b/sys/arch/sparc/sparc/memeccreg.h
new file mode 100644
index 00000000000..d81904c4499
--- /dev/null
+++ b/sys/arch/sparc/sparc/memeccreg.h
@@ -0,0 +1,83 @@
+/* $OpenBSD: memeccreg.h,v 1.1 2014/11/22 22:48:38 miod Exp $ */
+/* $NetBSD: memeccreg.h,v 1.2 2008/04/28 20:23:36 martin Exp $ */
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Paul Kranenburg.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ECC memory control.
+ */
+
+/* Register offsets */
+#define ECC_EN_REG 0
+#define ECC_FSR_REG 8
+#define ECC_AFR0_REG 16
+#define ECC_AFR1_REG 20
+#define ECC_DIAG_REG 24
+
+/* ECC Memory Enable register */
+#define ECC_EN_EE 0x00000001 /* Enable ECC checking */
+#define ECC_EN_EI 0x00000002 /* Interrupt on correctable error */
+#define ECC_EN_VER 0x0f000000 /* Version */
+#define ECC_EN_IMPL 0xf0000000 /* Implementation Id */
+
+/* ECC Memory Fault Status register */
+#define ECC_FSR_CE 0x00000001 /* Correctable error */
+#define ECC_FSR_TO 0x00000004 /* Timeout on write */
+#define ECC_FSR_UE 0x00000008 /* Uncorrectable error */
+#define ECC_FSR_DW 0x000000f0 /* Index of double word in block */
+#define ECC_FSR_SYND 0x0000ff00 /* Syndrome for correctable error */
+#define ECC_FSR_ME 0x00010000 /* Multiple errors */
+
+/*
+ * ECC Memory Fault Address registers
+ * There are two of these. The first has bits 32-35 of the faulting
+ * physical address and assorted MBus bits. The second has bits
+ * 0-31 of the faulting physical address.
+ */
+#define ECC_AFR_PAH 0x0000000f /* PA[31-35] */
+#define ECC_AFR_TYPE 0x000000f0 /* Transaction type */
+#define ECC_AFR_SIZE 0x00000700 /* Transaction size */
+#define ECC_AFR_C 0x00000800 /* Mapped cacheable */
+#define ECC_AFR_LOCK 0x00001000 /* Error occurred in atomic cycle */
+#define ECC_AFR_MBL 0x00002000 /* Boot mode */
+#define ECC_AFR_VA 0x003fc000 /* VA[12-19] (superset bits) */
+#define ECC_AFR_S 0x08000000 /* Access was in supervisor mode */
+#define ECC_AFR_MID 0xf0000000 /* Module code */
+
+/* ECC Diagnostic register */
+#define ECC_DR_CBX 0x00000001
+#define ECC_DR_CB0 0x00000002
+#define ECC_DR_CB1 0x00000004
+#define ECC_DR_CB2 0x00000008
+#define ECC_DR_CB4 0x00000010
+#define ECC_DR_CB8 0x00000020
+#define ECC_DR_CB16 0x00000040
+#define ECC_DR_CB32 0x00000080
+#define ECC_DR_DMODE 0x00000c00