summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorpk <pk@NetBSD.org>1998-09-18 20:18:10 +0000
committerpk <pk@NetBSD.org>1998-09-18 20:18:10 +0000
commitb3c7ebb7cd9c0ae73ef4ef960020cee560feea27 (patch)
tree4eb930bf0ecb5ebf49fb2d180b8db2db8a4108fb /sys
parentaed39ca72c9c86102a54b4cb378276d374ce08cd (diff)
Handle ECC memory control found on a number of machines.
Also defines an entry point for memory errors reported by module interrupts.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/sparc/sparc/memecc.c151
-rw-r--r--sys/arch/sparc/sparc/memeccreg.h100
2 files changed, 251 insertions, 0 deletions
diff --git a/sys/arch/sparc/sparc/memecc.c b/sys/arch/sparc/sparc/memecc.c
new file mode 100644
index 00000000000..d5f3abcd0ca
--- /dev/null
+++ b/sys/arch/sparc/sparc/memecc.c
@@ -0,0 +1,151 @@
+/* $NetBSD: memecc.c,v 1.1 1998/09/18 20:18:10 pk 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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/bus.h>
+#include <machine/autoconf.h>
+#include <sparc/sparc/memeccreg.h>
+
+struct memecc_softc {
+ struct device sc_dev; /* base device */
+ bus_space_tag_t sc_bt;
+ bus_space_handle_t sc_bh;
+};
+
+struct memecc_softc *memecc_sc;
+
+/* autoconfiguration driver */
+static void memecc_attach __P((struct device *, struct device *, void *));
+static int memecc_match __P((struct device *, struct cfdata *, void *));
+static int memecc_error __P((void));
+
+extern int (*memerr_handler) __P((void));
+
+struct cfattach memecc_ca = {
+ sizeof(struct memecc_softc), memecc_match, memecc_attach
+};
+
+int
+memecc_match(parent, cf, aux)
+ struct device *parent;
+ struct cfdata *cf;
+ void *aux;
+{
+ struct mainbus_attach_args *ma = aux;
+
+ return (strcmp("eccmemctl", ma->ma_name) == 0);
+}
+
+/*
+ * Attach the device.
+ */
+void
+memecc_attach(parent, self, aux)
+ struct device *parent;
+ struct device *self;
+ void *aux;
+{
+ struct memecc_softc *sc = (struct memecc_softc *)self;
+ struct mainbus_attach_args *ma = aux;
+ int node;
+ u_int32_t reg;
+
+ sc->sc_bt = ma->ma_bustag;
+ node = ma->ma_node;
+
+ /*
+ * Map registers
+ */
+ if (bus_space_map2(
+ ma->ma_bustag,
+ ma->ma_iospace,
+ ma->ma_paddr,
+ ma->ma_size,
+ 0,
+ 0,
+ &sc->sc_bh) != 0) {
+ printf("memecc_attach: cannot map registers\n");
+ return;
+ }
+
+ reg = bus_space_read_4(sc->sc_bt, sc->sc_bh, 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;
+ bus_space_write_4(sc->sc_bt, sc->sc_bh, 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()
+{
+ bus_space_handle_t bh = memecc_sc->sc_bh;
+ u_int32_t efsr, efar0, efar1;
+ char bits[64];
+
+ efsr = bus_space_read_4(memecc_sc->sc_bt, bh, ECC_FSR_REG);
+ efar0 = bus_space_read_4(memecc_sc->sc_bt, bh, ECC_AFR0_REG);
+ efar1 = bus_space_read_4(memecc_sc->sc_bt, bh, ECC_AFR1_REG);
+ printf("memory error:\n\tEFSR: %s\n",
+ bitmask_snprintf(efsr, ECC_FSR_BITS, bits, sizeof(bits)));
+ printf("\tMBus transaction: %s\n",
+ bitmask_snprintf(efar0, ECC_AFR_BITS, bits, sizeof(bits)));
+ printf("\taddress: 0x%x%x\n", efar0 & ECC_AFR_PAH, efar1);
+
+ /* Unlock registers and clear interrupt */
+ bus_space_write_4(memecc_sc->sc_bt, bh, 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..5fd43c85982
--- /dev/null
+++ b/sys/arch/sparc/sparc/memeccreg.h
@@ -0,0 +1,100 @@
+/* $NetBSD: memeccreg.h,v 1.1 1998/09/18 20:18:10 pk 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 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 */
+#define ECC_FSR_BITS "\177\020" \
+ "b\0CE\0b\2TO\0b\3UE\0" \
+ "f\4\4DW\0f\10\10SYNDROME\0b\20ME\0"
+
+/*
+ * 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 */
+#define ECC_AFR_BITS "\177\020" \
+ "f\0\4VAH\0f\4\4TYPE\0f\10\3SIZE\0" \
+ "b\13C\0b\14LOCK\0b\15MBL\0" \
+ "f\16\10VA\0b\33S\0f\34\4MID\0"
+
+/* 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
+#define ECC_DR_BITS "\177\020" \
+ "f\12\2DMODE\0=\0NORMAL\0=\1GEN\0=\2DETECT\0" \
+ "f\0\8CHECK BITS\0"
+