* [U-Boot] [PATCH 1/7] 83xx: Add CCSR DDR register offsets
2009-11-09 23:37 [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update Peter Tyser
@ 2009-11-09 23:37 ` Peter Tyser
2009-11-09 23:37 ` [U-Boot] [PATCH 2/7] 85xx/86xx: Add ECC error injection defines Peter Tyser
` (6 subsequent siblings)
7 siblings, 0 replies; 24+ messages in thread
From: Peter Tyser @ 2009-11-09 23:37 UTC (permalink / raw)
To: u-boot
Using the same naming convention for CCSR register addresses between the
83xx, 85xx, and 86xx platforms makes it a bit easier to share code
between them.
A small amount of asthetic cleanup was also done in this change.
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
---
include/asm-ppc/immap_83xx.h | 22 +++++++++++++++-------
1 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/include/asm-ppc/immap_83xx.h b/include/asm-ppc/immap_83xx.h
index c60a7d2..a9d0698 100644
--- a/include/asm-ppc/immap_83xx.h
+++ b/include/asm-ppc/immap_83xx.h
@@ -858,14 +858,22 @@ typedef struct immap {
} immap_t;
#endif
-#define CONFIG_SYS_MPC83xx_DMA_OFFSET (0x8000)
-#define CONFIG_SYS_MPC83xx_DMA_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DMA_OFFSET)
-#define CONFIG_SYS_MPC83xx_ESDHC_OFFSET (0x2e000)
-#define CONFIG_SYS_MPC83xx_ESDHC_ADDR (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_ESDHC_OFFSET)
-
+#define CONFIG_SYS_MPC83xx_DDR_OFFSET 0x2000
+#define CONFIG_SYS_MPC83xx_DMA_OFFSET 0x8000
+#define CONFIG_SYS_MPC83xx_DDR2_OFFSET 0xd000
#ifndef CONFIG_SYS_MPC83xx_USB_OFFSET
-#define CONFIG_SYS_MPC83xx_USB_OFFSET 0x23000
+#define CONFIG_SYS_MPC83xx_USB_OFFSET 0x23000
#endif
+#define CONFIG_SYS_MPC83xx_ESDHC_OFFSET 0x2e000
+
+#define CONFIG_SYS_MPC83xx_DDR_ADDR \
+ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DDR_OFFSET)
+#define CONFIG_SYS_MPC83xx_DDR2_ADDR \
+ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DDR2_OFFSET)
+#define CONFIG_SYS_MPC83xx_DMA_ADDR \
+ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_DMA_OFFSET)
+#define CONFIG_SYS_MPC83xx_ESDHC_ADDR \
+ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_ESDHC_OFFSET)
#define CONFIG_SYS_MPC83xx_USB_ADDR \
- (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_USB_OFFSET)
+ (CONFIG_SYS_IMMR + CONFIG_SYS_MPC83xx_USB_OFFSET)
#endif /* __IMMAP_83xx__ */
--
1.6.2.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [U-Boot] [PATCH 2/7] 85xx/86xx: Add ECC error injection defines
2009-11-09 23:37 [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update Peter Tyser
2009-11-09 23:37 ` [U-Boot] [PATCH 1/7] 83xx: Add CCSR DDR register offsets Peter Tyser
@ 2009-11-09 23:37 ` Peter Tyser
2009-11-09 23:37 ` [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support Peter Tyser
` (5 subsequent siblings)
7 siblings, 0 replies; 24+ messages in thread
From: Peter Tyser @ 2009-11-09 23:37 UTC (permalink / raw)
To: u-boot
These defines are needed for the upcoming ECC driver.
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
---
include/asm-ppc/immap_85xx.h | 4 ++++
include/asm-ppc/immap_86xx.h | 3 +++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/include/asm-ppc/immap_85xx.h b/include/asm-ppc/immap_85xx.h
index 4194295..b283986 100644
--- a/include/asm-ppc/immap_85xx.h
+++ b/include/asm-ppc/immap_85xx.h
@@ -167,6 +167,10 @@ typedef struct ccsr_ddr {
u32 data_err_inject_hi; /* Data Path Err Injection Mask High */
u32 data_err_inject_lo; /* Data Path Err Injection Mask Low */
u32 ecc_err_inject; /* Data Path Err Injection Mask ECC */
+#define ECC_ERR_INJECT_APIEN 0x00010000 /* Address Parity Injection */
+#define ECC_ERR_INJECT_EMB 0x00000200 /* ECC Mirror Byte */
+#define ECC_ERR_INJECT_EIEN 0x00000100 /* Error Injection Enable */
+#define ECC_ERR_INJECT_EEIM 0x000000ff /* ECC Erroe Injection Enable */
u8 res9[20];
u32 capture_data_hi; /* Data Path Read Capture High */
u32 capture_data_lo; /* Data Path Read Capture Low */
diff --git a/include/asm-ppc/immap_86xx.h b/include/asm-ppc/immap_86xx.h
index fdfc654..384912f 100644
--- a/include/asm-ppc/immap_86xx.h
+++ b/include/asm-ppc/immap_86xx.h
@@ -135,6 +135,9 @@ typedef struct ccsr_ddr {
uint data_err_inject_hi; /* 0x2e00 - DDR Memory Data Path Error Injection Mask High */
uint data_err_inject_lo; /* 0x2e04 - DDR Memory Data Path Error Injection Mask Low */
uint ecc_err_inject; /* 0x2e08 - DDR Memory Data Path Error Injection Mask ECC */
+#define ECC_ERR_INJECT_EMB 0x00000200 /* ECC Mirror Byte */
+#define ECC_ERR_INJECT_EIEN 0x00000100 /* Error Injection Enable */
+#define ECC_ERR_INJECT_EEIM 0x000000ff /* ECC Erroe Injection Enable */
char res12[20];
uint capture_data_hi; /* 0x2e20 - DDR Memory Data Path Read Capture High */
uint capture_data_lo; /* 0x2e24 - DDR Memory Data Path Read Capture Low */
--
1.6.2.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-09 23:37 [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update Peter Tyser
2009-11-09 23:37 ` [U-Boot] [PATCH 1/7] 83xx: Add CCSR DDR register offsets Peter Tyser
2009-11-09 23:37 ` [U-Boot] [PATCH 2/7] 85xx/86xx: Add ECC error injection defines Peter Tyser
@ 2009-11-09 23:37 ` Peter Tyser
2009-11-10 0:25 ` Liu Dave-R63238
2009-11-09 23:37 ` [U-Boot] [PATCH 4/7] 83xx: Migrate CONFIG_DDR_ECC_CMD to CONFIG_EDAC_FSL_ECC Peter Tyser
` (4 subsequent siblings)
7 siblings, 1 reply; 24+ messages in thread
From: Peter Tyser @ 2009-11-09 23:37 UTC (permalink / raw)
To: u-boot
Add a new 'ecc' command to interact with the 83xx, 85xx, and 86xx DDR
ECC registers. The 'ecc' command can inject data/ECC errors to simulate
errors and provides an 'info' subcommand which displays ECC error
information such as failure address, read vs expected data/ECC,
physical signal which failed, single-bit error count, and multiple bit
error occurrence. An example of the 'ecc info' command follows:
WARNING: ECC error in DDR Controller 0
Addr: 0x0_01001000
Data: 0x00000001_00000000 ECC: 0x00
Expect: 0x00000000_00000000 ECC: 0x00
Net: DATA32
Syndrome: 0xce
Single-Bit errors: 0x40
Attrib: 0x30112001
Detect: 0x80000004 (MME, SBE)
This new 'ecc' command support was placed in a new drives/edac
directory which can be used to support general Error Detection and
Correction (EDAC) code similar to Linux.
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
Signed-off-by: John Schmoller <jschmoller@xes-inc.com>
---
Makefile | 2 +
drivers/edac/Makefile | 46 +++++
drivers/edac/fsl_8xxx_ecc.c | 381 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 429 insertions(+), 0 deletions(-)
create mode 100644 drivers/edac/Makefile
create mode 100644 drivers/edac/fsl_8xxx_ecc.c
diff --git a/Makefile b/Makefile
index bed9469..3663780 100644
--- a/Makefile
+++ b/Makefile
@@ -204,6 +204,7 @@ LIBS += disk/libdisk.a
LIBS += drivers/bios_emulator/libatibiosemu.a
LIBS += drivers/block/libblock.a
LIBS += drivers/dma/libdma.a
+LIBS += drivers/edac/libedac.a
LIBS += drivers/fpga/libfpga.a
LIBS += drivers/gpio/libgpio.a
LIBS += drivers/hwmon/libhwmon.a
@@ -416,6 +417,7 @@ TAG_SUBDIRS += disk
TAG_SUBDIRS += common
TAG_SUBDIRS += drivers/bios_emulator
TAG_SUBDIRS += drivers/block
+TAG_SUBDIRS += drivers/edac
TAG_SUBDIRS += drivers/gpio
TAG_SUBDIRS += drivers/hwmon
TAG_SUBDIRS += drivers/i2c
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
new file mode 100644
index 0000000..92ab497
--- /dev/null
+++ b/drivers/edac/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB := $(obj)libedac.a
+
+COBJS-$(CONFIG_EDAC_FSL_ECC) += fsl_8xxx_ecc.o
+
+COBJS := $(COBJS-y)
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/edac/fsl_8xxx_ecc.c b/drivers/edac/fsl_8xxx_ecc.c
new file mode 100644
index 0000000..8f3bc7e
--- /dev/null
+++ b/drivers/edac/fsl_8xxx_ecc.c
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2009 Extreme Engineering Solutions, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#if defined(CONFIG_MPC85xx)
+#include <mpc85xx.h>
+#elif defined(CONFIG_MPC86xx)
+#include <mpc86xx.h>
+#elif defined(CONFIG_MPC83xx)
+#include <mpc83xx.h>
+#endif
+
+/* Provide a common name for DDR addresses on 83xx/85xx/86xx */
+#if defined(CONFIG_MPC85xx)
+#define MPC8xxx_DDR_ADDR CONFIG_SYS_MPC85xx_DDR_ADDR
+#define MPC8xxx_DDR2_ADDR CONFIG_SYS_MPC85xx_DDR2_ADDR
+#elif defined(CONFIG_MPC86xx)
+#define MPC8xxx_DDR_ADDR CONFIG_SYS_MPC86xx_DDR_ADDR
+#define MPC8xxx_DDR2_ADDR CONFIG_SYS_MPC86xx_DDR2_ADDR
+#elif defined(CONFIG_MPC83xx)
+#define MPC8xxx_DDR_ADDR CONFIG_SYS_MPC83xx_DDR_ADDR
+#define MPC8xxx_DDR2_ADDR CONFIG_SYS_MPC83xx_DDR2_ADDR
+/* 83xx uses a different structure name, but has the same register names */
+typedef ddr83xx_t ccsr_ddr_t;
+
+/* some 83xx support 2 controllers, but no boards use the 2nd one yet */
+#ifndef CONFIG_NUM_DDR_CONTROLLERS
+#define CONFIG_NUM_DDR_CONTROLLERS 1
+#endif
+#else
+#error "ECC not supported on this platform"
+#endif
+
+/*
+ * Taken from table 8-55 in the MPC8641 User's Manual and/or 9-61 in the
+ * MPC8572 User's Manual. Each line represents a syndrome bit column as a
+ * 64-bit value, but split into an upper and lower 32-bit chunk. The labels
+ * below correspond to Freescale's manuals.
+ */
+static unsigned int ecc_table[16] = {
+ /* MSB LSB */
+ /* [0:31] [32:63] */
+ 0xf00fe11e, 0xc33c0ff7, /* Syndrome bit 7 */
+ 0x00ff00ff, 0x00fff0ff,
+ 0x0f0f0f0f, 0x0f0fff00,
+ 0x11113333, 0x7777000f,
+ 0x22224444, 0x8888222f,
+ 0x44448888, 0xffff4441,
+ 0x8888ffff, 0x11118882,
+ 0xffff1111, 0x22221114, /* Syndrome bit 0 */
+};
+
+/*
+ * Calculate the correct ECC value for a 64-bit integer specified by high:low
+ */
+static uint8_t calculate_ecc(uint32_t high, uint32_t low)
+{
+ uint32_t mask_low;
+ uint32_t mask_high;
+ int bit_cnt;
+ uint8_t ecc = 0;
+ int i;
+ int j;
+
+ for (i = 0; i < 8; i++) {
+ mask_high = ecc_table[i * 2];
+ mask_low = ecc_table[i * 2 + 1];
+ bit_cnt = 0;
+
+ for (j = 0; j < 32; j++) {
+ if ((mask_high >> j) & 1)
+ bit_cnt ^= (high >> j) & 1;
+ if ((mask_low >> j) & 1)
+ bit_cnt ^= (low >> j) & 1;
+ }
+
+ ecc |= bit_cnt << i;
+ }
+
+ return ecc;
+}
+
+/*
+ * Create the syndrome code which is generated if the data line specified by
+ * 'bit' failed. Eg generate the 8-bit codes seen in Table 8-55 in the MPC8641
+ * User's Manual and 9-61 in the MPC8572 User's Manual.
+ */
+static uint8_t syndrome_from_bit(unsigned int bit) {
+ int i;
+ uint8_t syndrome = 0;
+
+ /*
+ * Cycle through the upper or lower 32-bit portion of each value in
+ * ecc_table depending on if 'bit' is in the upper or lower half of
+ * 64-bit data.
+ */
+ for (i = bit < 32; i < 16; i += 2)
+ syndrome |= ((ecc_table[i] >> (bit % 32)) & 1) << (i / 2);
+
+ return syndrome;
+}
+
+/*
+ * Decode data and ecc syndrome to determine what went wrong
+ * Note: This can only decode single-bit errors
+ */
+static void ecc_decode(uint32_t data_hi, uint32_t data_lo, uint32_t ecc)
+{
+ int i;
+ int bad_data_bit = -1;
+ int bad_ecc_bit = -1;
+ uint8_t syndrome;
+
+ /*
+ * Calculate the ECC of the captured data and XOR it with the captured
+ * ECC to find an ECC syndrome value
+ */
+ syndrome = calculate_ecc(data_hi, data_lo) ^ ecc;
+
+ /* Check if a data line is stuck... */
+ for (i = 0; i < 64; i++) {
+ if (syndrome == syndrome_from_bit(i)) {
+ /*
+ * Save absolute position for printing out later.
+ * Note that we are recording the bit failure address
+ * with respect to the DRAM chips, not the CPU. For
+ * example, if the least significant data bit fails,
+ * we print out that DATA0 failed, not DATA63 which is
+ * how the CPU pinout is labeled.
+ */
+ bad_data_bit = i;
+
+ /* Convert 'data_[hi|low]' to their expected value */
+ data_hi ^= 1 << (bad_data_bit - 32),
+ data_lo ^= 1 << bad_data_bit;
+ break;
+ }
+ }
+
+ /* If data is correct, check ECC bits for errors... */
+ if (bad_data_bit == -1) {
+ for (i = 0; i < 8; i++) {
+ /*
+ * Note that we are recording the bit failure address
+ * with respect to the DRAM chips, not the CPU. For
+ * example, if the least significant ECC bit fails,
+ * we print out that ECC0 failed, not ECC7 which is
+ * how the CPU pinout is labeled. See Table 9-62 in
+ * the MPC8572 user's manual for additional details.
+ */
+ if ((syndrome >> i) & 0x1) {
+ bad_ecc_bit = i;
+
+ /* Convert 'ecc' to its expected value */
+ ecc ^= (1 << bad_ecc_bit) & 0xff;
+ break;
+ }
+ }
+ }
+
+ /* Print expected data and ecc */
+ printf("\tExpect:\t0x%08x_%08x\tECC:\t0x%02x\n", data_hi, data_lo, ecc);
+
+ /* Print data or ECC net which caused ECC error */
+ if (bad_ecc_bit != -1)
+ printf("\tNet:\tECC%d\n", bad_ecc_bit);
+ else
+ printf("\tNet:\tDATA%d\n", bad_data_bit);
+
+ printf("\tSyndrome: 0x%x\n", syndrome);
+}
+
+int ecc_count(void)
+{
+ int count = 0;
+ int i;
+ volatile ccsr_ddr_t* ddr[] = {
+ (void*)MPC8xxx_DDR_ADDR,
+#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
+ (void*)MPC8xxx_DDR2_ADDR,
+#endif
+ };
+
+ for (i = 0; i < ARRAY_SIZE(ddr); i++) {
+ /* Add up single-bit errors */
+ count += in_be32(&ddr[i]->err_sbe) & 0xff;
+
+ /* Add 1 for a multiple-bit error */
+ if (in_be32(&ddr[i]->err_detect) & 0x8)
+ count++;
+ }
+
+ return count;
+}
+
+void ecc_info(void)
+{
+ int controller;
+ uint32_t data_hi;
+ uint32_t data_lo;
+ uint32_t ecc;
+ uint32_t err_detect;
+ uint32_t sbe;
+ uint32_t attributes;
+ uint32_t address;
+ uint32_t ext_address;
+ volatile ccsr_ddr_t* ddr[] = {
+ (void*)MPC8xxx_DDR_ADDR,
+#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
+ (void*)MPC8xxx_DDR2_ADDR,
+#endif
+ };
+
+ for (controller = 0;
+ controller < CONFIG_NUM_DDR_CONTROLLERS;
+ controller ++) {
+ /* Check for a single or multiple-bit ECC error */
+ sbe = in_be32(&ddr[controller]->err_sbe) & 0xff;
+ err_detect = in_be32(&ddr[controller]->err_detect);
+ if (!sbe && !(err_detect & 0x8))
+ continue;
+
+ /* Read in the rest of the ECC error info */
+ data_hi = in_be32(&ddr[controller]->capture_data_hi);
+ data_lo = in_be32(&ddr[controller]->capture_data_lo),
+ ecc = in_be32(&ddr[controller]->capture_ecc) & 0xff;
+ attributes = in_be32(&ddr[controller]->capture_attributes);
+ address = in_be32(&ddr[controller]->capture_address);
+ ext_address = in_be32(&ddr[controller]->capture_ext_address) & 0xf;
+
+ printf("\nWARNING: ECC error in DDR Controller %d\n", controller);
+ printf("\tAddr:\t0x%01x_%08x\n", ext_address, address);
+ printf("\tData:\t0x%08x_%08x\tECC:\t0x%02x\n",
+ data_hi, data_lo, ecc);
+
+ if (err_detect & 0x8) {
+ printf("ERROR: Multiple-bit errors!!!\n");
+ } else if (sbe) {
+ /* Analyze which data or ecc line is the culprit. */
+ ecc_decode(data_hi, data_lo, ecc);
+ }
+
+ printf("\tSingle-Bit errors: 0x%02x\n", sbe);
+ printf("\tAttrib:\t0x%08x\n", attributes);
+ printf("\tDetect:\t0x%08x", err_detect);
+ if(err_detect)
+ printf(" (");
+ if(err_detect & 0x80000000)
+ printf("MME, ");
+ if(err_detect & 0x100)
+ printf("APE, ");
+ if(err_detect & 0x80)
+ printf("ACE, ");
+ if(err_detect & 0x8)
+ printf("MBE, ");
+ if(err_detect & 0x4)
+ printf("SBE, ");
+ if(err_detect & 0x1)
+ printf("MSE, ");
+ if(err_detect)
+ printf("\b\b)\n");
+
+ printf("\n");
+
+ /* Clear ECC error info and count */
+ out_be32(&ddr[controller]->err_detect,
+ in_be32(&ddr[controller]->err_detect));
+ out_be32(&ddr[controller]->err_sbe,
+ in_be32(&ddr[controller]->err_sbe) & ~0xff);
+ }
+}
+
+static int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ static uint controller = 0;
+ uint32_t ecc_mask = 0;
+ uint32_t mask;
+ int count;
+ volatile ccsr_ddr_t* ddr[] = {
+ (void*)MPC8xxx_DDR_ADDR,
+#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
+ (void*)MPC8xxx_DDR2_ADDR,
+#endif
+ };
+
+ if (argc == 2) {
+ if (argv[1][0] == 'i') {
+ /* 'ecc info' */
+ count = ecc_count();
+ if (count) {
+ ecc_info();
+ return count;
+ }
+
+ printf("No ECC errors have occurred\n");
+
+ return 0;
+ } else if (argv[1][0] == 'c') {
+ /* 'ecc ctrl' */
+ printf("Active controller: %d\n", controller);
+ return 0;
+ }
+ } else if (argc == 3) {
+ if (argv[1][0] == 'c') {
+ /* 'ecc ctrl num' */
+ controller = simple_strtoul(argv[2], NULL, 16);
+ if (controller > (CONFIG_NUM_DDR_CONTROLLERS - 1)) {
+ printf("Invalid controller number\n");
+ controller = 0;
+ return 1;
+ }
+ return 0;
+ } else if ((argv[1][0] == 'i') && (argv[2][0] == 'o')) {
+ /* 'ecc inject off' */
+ out_be32(&ddr[controller]->ecc_err_inject, 0);
+ out_be32(&ddr[controller]->data_err_inject_lo, 0);
+ out_be32(&ddr[controller]->data_err_inject_hi, 0);
+ return 0;
+ }
+ } else if (argc == 4) {
+ /* 'ecc inject <high|low|ecc> mask' */
+ mask = simple_strtoul(argv[3], NULL, 16);
+ switch (argv[2][0]) {
+ case 'h':
+ out_be32(&ddr[controller]->data_err_inject_hi, mask);
+ break;
+ case 'l':
+ out_be32(&ddr[controller]->data_err_inject_lo, mask);
+ break;
+ case 'e':
+ ecc_mask = mask & ECC_ERR_INJECT_EEIM;
+ break;
+ default:
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ /* Enable error injection */
+ out_be32(&ddr[controller]->ecc_err_inject,
+ ecc_mask | ECC_ERR_INJECT_EIEN);
+ return 0;
+ }
+
+ cmd_usage(cmdtp);
+ return 1;
+}
+
+U_BOOT_CMD(ecc, 5, 0, do_ecc,
+ "support for DDR ECC features",
+ "info - print ECC information\n"
+#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
+ "ecc ctrl [num]\n"
+ "\t-Set active controller to 'num', or display active controller\n"
+#endif
+ "ecc inject high <mask>\n"
+ "ecc inject low <mask>\n"
+ "ecc inject ecc <mask>\n"
+ "\t- XOR 'mask' with high/low data or ECC\n"
+ "ecc inject off\n"
+ "\t- disable error injection\n"
+);
--
1.6.2.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-09 23:37 ` [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support Peter Tyser
@ 2009-11-10 0:25 ` Liu Dave-R63238
2009-11-10 0:32 ` Peter Tyser
0 siblings, 1 reply; 24+ messages in thread
From: Liu Dave-R63238 @ 2009-11-10 0:25 UTC (permalink / raw)
To: u-boot
How to use these command to test the ECC?
Specially, how to inject multi error in 64bit data bus?
Thanks, Dave
> -----Original Message-----
> From: u-boot-bounces at lists.denx.de
> [mailto:u-boot-bounces at lists.denx.de] On Behalf Of Peter Tyser
> Sent: Tuesday, November 10, 2009 7:37 AM
> To: u-boot at lists.denx.de
> Cc: Peter Tyser; Phillips Kim-R1AAHA; galak at kernel.crashing.org
> Subject: [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
>
> Add a new 'ecc' command to interact with the 83xx, 85xx, and 86xx DDR
> ECC registers. The 'ecc' command can inject data/ECC errors
> to simulate
> errors and provides an 'info' subcommand which displays ECC error
> information such as failure address, read vs expected data/ECC,
> physical signal which failed, single-bit error count, and multiple bit
> error occurrence. An example of the 'ecc info' command follows:
>
> WARNING: ECC error in DDR Controller 0
> Addr: 0x0_01001000
> Data: 0x00000001_00000000 ECC: 0x00
> Expect: 0x00000000_00000000 ECC: 0x00
> Net: DATA32
> Syndrome: 0xce
> Single-Bit errors: 0x40
> Attrib: 0x30112001
> Detect: 0x80000004 (MME, SBE)
>
> This new 'ecc' command support was placed in a new drives/edac
> directory which can be used to support general Error Detection and
> Correction (EDAC) code similar to Linux.
>
> Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
> Signed-off-by: John Schmoller <jschmoller@xes-inc.com>
> ---
> Makefile | 2 +
> drivers/edac/Makefile | 46 +++++
> drivers/edac/fsl_8xxx_ecc.c | 381
> +++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 429 insertions(+), 0 deletions(-)
> create mode 100644 drivers/edac/Makefile
> create mode 100644 drivers/edac/fsl_8xxx_ecc.c
>
> diff --git a/Makefile b/Makefile
> index bed9469..3663780 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -204,6 +204,7 @@ LIBS += disk/libdisk.a
> LIBS += drivers/bios_emulator/libatibiosemu.a
> LIBS += drivers/block/libblock.a
> LIBS += drivers/dma/libdma.a
> +LIBS += drivers/edac/libedac.a
> LIBS += drivers/fpga/libfpga.a
> LIBS += drivers/gpio/libgpio.a
> LIBS += drivers/hwmon/libhwmon.a
> @@ -416,6 +417,7 @@ TAG_SUBDIRS += disk
> TAG_SUBDIRS += common
> TAG_SUBDIRS += drivers/bios_emulator
> TAG_SUBDIRS += drivers/block
> +TAG_SUBDIRS += drivers/edac
> TAG_SUBDIRS += drivers/gpio
> TAG_SUBDIRS += drivers/hwmon
> TAG_SUBDIRS += drivers/i2c
> diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
> new file mode 100644
> index 0000000..92ab497
> --- /dev/null
> +++ b/drivers/edac/Makefile
> @@ -0,0 +1,46 @@
> +#
> +# (C) Copyright 2000-2007
> +# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> +#
> +# See file CREDITS for list of people who contributed to this
> +# project.
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License as
> +# published by the Free Software Foundation; either version 2 of
> +# the License, or (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> +# MA 02111-1307 USA
> +#
> +
> +include $(TOPDIR)/config.mk
> +
> +LIB := $(obj)libedac.a
> +
> +COBJS-$(CONFIG_EDAC_FSL_ECC) += fsl_8xxx_ecc.o
> +
> +COBJS := $(COBJS-y)
> +SRCS := $(COBJS:.o=.c)
> +OBJS := $(addprefix $(obj),$(COBJS))
> +
> +all: $(LIB)
> +
> +$(LIB): $(obj).depend $(OBJS)
> + $(AR) $(ARFLAGS) $@ $(OBJS)
> +
> +#############################################################
> ############
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#############################################################
> ############
> diff --git a/drivers/edac/fsl_8xxx_ecc.c b/drivers/edac/fsl_8xxx_ecc.c
> new file mode 100644
> index 0000000..8f3bc7e
> --- /dev/null
> +++ b/drivers/edac/fsl_8xxx_ecc.c
> @@ -0,0 +1,381 @@
> +/*
> + * Copyright 2009 Extreme Engineering Solutions, Inc.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#if defined(CONFIG_MPC85xx)
> +#include <mpc85xx.h>
> +#elif defined(CONFIG_MPC86xx)
> +#include <mpc86xx.h>
> +#elif defined(CONFIG_MPC83xx)
> +#include <mpc83xx.h>
> +#endif
> +
> +/* Provide a common name for DDR addresses on 83xx/85xx/86xx */
> +#if defined(CONFIG_MPC85xx)
> +#define MPC8xxx_DDR_ADDR CONFIG_SYS_MPC85xx_DDR_ADDR
> +#define MPC8xxx_DDR2_ADDR CONFIG_SYS_MPC85xx_DDR2_ADDR
> +#elif defined(CONFIG_MPC86xx)
> +#define MPC8xxx_DDR_ADDR CONFIG_SYS_MPC86xx_DDR_ADDR
> +#define MPC8xxx_DDR2_ADDR CONFIG_SYS_MPC86xx_DDR2_ADDR
> +#elif defined(CONFIG_MPC83xx)
> +#define MPC8xxx_DDR_ADDR CONFIG_SYS_MPC83xx_DDR_ADDR
> +#define MPC8xxx_DDR2_ADDR CONFIG_SYS_MPC83xx_DDR2_ADDR
> +/* 83xx uses a different structure name, but has the same
> register names */
> +typedef ddr83xx_t ccsr_ddr_t;
> +
> +/* some 83xx support 2 controllers, but no boards use the
> 2nd one yet */
> +#ifndef CONFIG_NUM_DDR_CONTROLLERS
> +#define CONFIG_NUM_DDR_CONTROLLERS 1
> +#endif
> +#else
> +#error "ECC not supported on this platform"
> +#endif
> +
> +/*
> + * Taken from table 8-55 in the MPC8641 User's Manual and/or
> 9-61 in the
> + * MPC8572 User's Manual. Each line represents a syndrome
> bit column as a
> + * 64-bit value, but split into an upper and lower 32-bit
> chunk. The labels
> + * below correspond to Freescale's manuals.
> + */
> +static unsigned int ecc_table[16] = {
> + /* MSB LSB */
> + /* [0:31] [32:63] */
> + 0xf00fe11e, 0xc33c0ff7, /* Syndrome bit 7 */
> + 0x00ff00ff, 0x00fff0ff,
> + 0x0f0f0f0f, 0x0f0fff00,
> + 0x11113333, 0x7777000f,
> + 0x22224444, 0x8888222f,
> + 0x44448888, 0xffff4441,
> + 0x8888ffff, 0x11118882,
> + 0xffff1111, 0x22221114, /* Syndrome bit 0 */
> +};
> +
> +/*
> + * Calculate the correct ECC value for a 64-bit integer
> specified by high:low
> + */
> +static uint8_t calculate_ecc(uint32_t high, uint32_t low)
> +{
> + uint32_t mask_low;
> + uint32_t mask_high;
> + int bit_cnt;
> + uint8_t ecc = 0;
> + int i;
> + int j;
> +
> + for (i = 0; i < 8; i++) {
> + mask_high = ecc_table[i * 2];
> + mask_low = ecc_table[i * 2 + 1];
> + bit_cnt = 0;
> +
> + for (j = 0; j < 32; j++) {
> + if ((mask_high >> j) & 1)
> + bit_cnt ^= (high >> j) & 1;
> + if ((mask_low >> j) & 1)
> + bit_cnt ^= (low >> j) & 1;
> + }
> +
> + ecc |= bit_cnt << i;
> + }
> +
> + return ecc;
> +}
> +
> +/*
> + * Create the syndrome code which is generated if the data
> line specified by
> + * 'bit' failed. Eg generate the 8-bit codes seen in Table
> 8-55 in the MPC8641
> + * User's Manual and 9-61 in the MPC8572 User's Manual.
> + */
> +static uint8_t syndrome_from_bit(unsigned int bit) {
> + int i;
> + uint8_t syndrome = 0;
> +
> + /*
> + * Cycle through the upper or lower 32-bit portion of
> each value in
> + * ecc_table depending on if 'bit' is in the upper or
> lower half of
> + * 64-bit data.
> + */
> + for (i = bit < 32; i < 16; i += 2)
> + syndrome |= ((ecc_table[i] >> (bit % 32)) & 1)
> << (i / 2);
> +
> + return syndrome;
> +}
> +
> +/*
> + * Decode data and ecc syndrome to determine what went wrong
> + * Note: This can only decode single-bit errors
> + */
> +static void ecc_decode(uint32_t data_hi, uint32_t data_lo,
> uint32_t ecc)
> +{
> + int i;
> + int bad_data_bit = -1;
> + int bad_ecc_bit = -1;
> + uint8_t syndrome;
> +
> + /*
> + * Calculate the ECC of the captured data and XOR it
> with the captured
> + * ECC to find an ECC syndrome value
> + */
> + syndrome = calculate_ecc(data_hi, data_lo) ^ ecc;
> +
> + /* Check if a data line is stuck... */
> + for (i = 0; i < 64; i++) {
> + if (syndrome == syndrome_from_bit(i)) {
> + /*
> + * Save absolute position for printing
> out later.
> + * Note that we are recording the bit
> failure address
> + * with respect to the DRAM chips, not
> the CPU. For
> + * example, if the least significant
> data bit fails,
> + * we print out that DATA0 failed, not
> DATA63 which is
> + * how the CPU pinout is labeled.
> + */
> + bad_data_bit = i;
> +
> + /* Convert 'data_[hi|low]' to their
> expected value */
> + data_hi ^= 1 << (bad_data_bit - 32),
> + data_lo ^= 1 << bad_data_bit;
> + break;
> + }
> + }
> +
> + /* If data is correct, check ECC bits for errors... */
> + if (bad_data_bit == -1) {
> + for (i = 0; i < 8; i++) {
> + /*
> + * Note that we are recording the bit
> failure address
> + * with respect to the DRAM chips, not
> the CPU. For
> + * example, if the least significant
> ECC bit fails,
> + * we print out that ECC0 failed, not
> ECC7 which is
> + * how the CPU pinout is labeled. See
> Table 9-62 in
> + * the MPC8572 user's manual for
> additional details.
> + */
> + if ((syndrome >> i) & 0x1) {
> + bad_ecc_bit = i;
> +
> + /* Convert 'ecc' to its
> expected value */
> + ecc ^= (1 << bad_ecc_bit) & 0xff;
> + break;
> + }
> + }
> + }
> +
> + /* Print expected data and ecc */
> + printf("\tExpect:\t0x%08x_%08x\tECC:\t0x%02x\n",
> data_hi, data_lo, ecc);
> +
> + /* Print data or ECC net which caused ECC error */
> + if (bad_ecc_bit != -1)
> + printf("\tNet:\tECC%d\n", bad_ecc_bit);
> + else
> + printf("\tNet:\tDATA%d\n", bad_data_bit);
> +
> + printf("\tSyndrome: 0x%x\n", syndrome);
> +}
> +
> +int ecc_count(void)
> +{
> + int count = 0;
> + int i;
> + volatile ccsr_ddr_t* ddr[] = {
> + (void*)MPC8xxx_DDR_ADDR,
> +#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
> + (void*)MPC8xxx_DDR2_ADDR,
> +#endif
> + };
> +
> + for (i = 0; i < ARRAY_SIZE(ddr); i++) {
> + /* Add up single-bit errors */
> + count += in_be32(&ddr[i]->err_sbe) & 0xff;
> +
> + /* Add 1 for a multiple-bit error */
> + if (in_be32(&ddr[i]->err_detect) & 0x8)
> + count++;
> + }
> +
> + return count;
> +}
> +
> +void ecc_info(void)
> +{
> + int controller;
> + uint32_t data_hi;
> + uint32_t data_lo;
> + uint32_t ecc;
> + uint32_t err_detect;
> + uint32_t sbe;
> + uint32_t attributes;
> + uint32_t address;
> + uint32_t ext_address;
> + volatile ccsr_ddr_t* ddr[] = {
> + (void*)MPC8xxx_DDR_ADDR,
> +#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
> + (void*)MPC8xxx_DDR2_ADDR,
> +#endif
> + };
> +
> + for (controller = 0;
> + controller < CONFIG_NUM_DDR_CONTROLLERS;
> + controller ++) {
> + /* Check for a single or multiple-bit ECC error */
> + sbe = in_be32(&ddr[controller]->err_sbe) & 0xff;
> + err_detect = in_be32(&ddr[controller]->err_detect);
> + if (!sbe && !(err_detect & 0x8))
> + continue;
> +
> + /* Read in the rest of the ECC error info */
> + data_hi = in_be32(&ddr[controller]->capture_data_hi);
> + data_lo = in_be32(&ddr[controller]->capture_data_lo),
> + ecc = in_be32(&ddr[controller]->capture_ecc) & 0xff;
> + attributes =
> in_be32(&ddr[controller]->capture_attributes);
> + address = in_be32(&ddr[controller]->capture_address);
> + ext_address =
> in_be32(&ddr[controller]->capture_ext_address) & 0xf;
> +
> + printf("\nWARNING: ECC error in DDR Controller
> %d\n", controller);
> + printf("\tAddr:\t0x%01x_%08x\n", ext_address, address);
> + printf("\tData:\t0x%08x_%08x\tECC:\t0x%02x\n",
> + data_hi, data_lo, ecc);
> +
> + if (err_detect & 0x8) {
> + printf("ERROR: Multiple-bit errors!!!\n");
> + } else if (sbe) {
> + /* Analyze which data or ecc line is
> the culprit. */
> + ecc_decode(data_hi, data_lo, ecc);
> + }
> +
> + printf("\tSingle-Bit errors: 0x%02x\n", sbe);
> + printf("\tAttrib:\t0x%08x\n", attributes);
> + printf("\tDetect:\t0x%08x", err_detect);
> + if(err_detect)
> + printf(" (");
> + if(err_detect & 0x80000000)
> + printf("MME, ");
> + if(err_detect & 0x100)
> + printf("APE, ");
> + if(err_detect & 0x80)
> + printf("ACE, ");
> + if(err_detect & 0x8)
> + printf("MBE, ");
> + if(err_detect & 0x4)
> + printf("SBE, ");
> + if(err_detect & 0x1)
> + printf("MSE, ");
> + if(err_detect)
> + printf("\b\b)\n");
> +
> + printf("\n");
> +
> + /* Clear ECC error info and count */
> + out_be32(&ddr[controller]->err_detect,
> + in_be32(&ddr[controller]->err_detect));
> + out_be32(&ddr[controller]->err_sbe,
> + in_be32(&ddr[controller]->err_sbe) & ~0xff);
> + }
> +}
> +
> +static int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc,
> char *argv[])
> +{
> + static uint controller = 0;
> + uint32_t ecc_mask = 0;
> + uint32_t mask;
> + int count;
> + volatile ccsr_ddr_t* ddr[] = {
> + (void*)MPC8xxx_DDR_ADDR,
> +#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
> + (void*)MPC8xxx_DDR2_ADDR,
> +#endif
> + };
> +
> + if (argc == 2) {
> + if (argv[1][0] == 'i') {
> + /* 'ecc info' */
> + count = ecc_count();
> + if (count) {
> + ecc_info();
> + return count;
> + }
> +
> + printf("No ECC errors have occurred\n");
> +
> + return 0;
> + } else if (argv[1][0] == 'c') {
> + /* 'ecc ctrl' */
> + printf("Active controller: %d\n", controller);
> + return 0;
> + }
> + } else if (argc == 3) {
> + if (argv[1][0] == 'c') {
> + /* 'ecc ctrl num' */
> + controller = simple_strtoul(argv[2], NULL, 16);
> + if (controller >
> (CONFIG_NUM_DDR_CONTROLLERS - 1)) {
> + printf("Invalid controller number\n");
> + controller = 0;
> + return 1;
> + }
> + return 0;
> + } else if ((argv[1][0] == 'i') && (argv[2][0] == 'o')) {
> + /* 'ecc inject off' */
> + out_be32(&ddr[controller]->ecc_err_inject, 0);
> +
> out_be32(&ddr[controller]->data_err_inject_lo, 0);
> +
> out_be32(&ddr[controller]->data_err_inject_hi, 0);
> + return 0;
> + }
> + } else if (argc == 4) {
> + /* 'ecc inject <high|low|ecc> mask' */
> + mask = simple_strtoul(argv[3], NULL, 16);
> + switch (argv[2][0]) {
> + case 'h':
> +
> out_be32(&ddr[controller]->data_err_inject_hi, mask);
> + break;
> + case 'l':
> +
> out_be32(&ddr[controller]->data_err_inject_lo, mask);
> + break;
> + case 'e':
> + ecc_mask = mask & ECC_ERR_INJECT_EEIM;
> + break;
> + default:
> + cmd_usage(cmdtp);
> + return 1;
> + }
> +
> + /* Enable error injection */
> + out_be32(&ddr[controller]->ecc_err_inject,
> + ecc_mask | ECC_ERR_INJECT_EIEN);
> + return 0;
> + }
> +
> + cmd_usage(cmdtp);
> + return 1;
> +}
> +
> +U_BOOT_CMD(ecc, 5, 0, do_ecc,
> + "support for DDR ECC features",
> + "info - print ECC information\n"
> +#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
> + "ecc ctrl [num]\n"
> + "\t-Set active controller to 'num', or display active
> controller\n"
> +#endif
> + "ecc inject high <mask>\n"
> + "ecc inject low <mask>\n"
> + "ecc inject ecc <mask>\n"
> + "\t- XOR 'mask' with high/low data or ECC\n"
> + "ecc inject off\n"
> + "\t- disable error injection\n"
> +);
> --
> 1.6.2.1
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 0:25 ` Liu Dave-R63238
@ 2009-11-10 0:32 ` Peter Tyser
2009-11-10 0:38 ` Liu Dave-R63238
0 siblings, 1 reply; 24+ messages in thread
From: Peter Tyser @ 2009-11-10 0:32 UTC (permalink / raw)
To: u-boot
On Tue, 2009-11-10 at 08:25 +0800, Liu Dave-R63238 wrote:
> How to use these command to test the ECC?
> Specially, how to inject multi error in 64bit data bus?
<snip>
> > +U_BOOT_CMD(ecc, 5, 0, do_ecc,
> > + "support for DDR ECC features",
> > + "info - print ECC information\n"
> > +#if (CONFIG_NUM_DDR_CONTROLLERS > 1)
> > + "ecc ctrl [num]\n"
> > + "\t-Set active controller to 'num', or display active
> > controller\n"
> > +#endif
> > + "ecc inject high <mask>\n"
> > + "ecc inject low <mask>\n"
> > + "ecc inject ecc <mask>\n"
> > + "\t- XOR 'mask' with high/low data or ECC\n"
> > + "ecc inject off\n"
> > + "\t- disable error injection\n"
> > +);
Hi Dave,
You can inject data in the upper/lower 32 bit data path, or in the ecc
path using the "ecc inject" command shown above. The inject command
takes a mask that is XORed with the proper data, eg "ecc inject low 0x5"
would result in data bits 0 and 2 always being swapped resulting in
multibit errors.
Or you could ground 2 data pins on the PCB:)
Peter
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 0:32 ` Peter Tyser
@ 2009-11-10 0:38 ` Liu Dave-R63238
2009-11-10 0:42 ` Liu Dave-R63238
0 siblings, 1 reply; 24+ messages in thread
From: Liu Dave-R63238 @ 2009-11-10 0:38 UTC (permalink / raw)
To: u-boot
> You can inject data in the upper/lower 32 bit data path, or in the ecc
> path using the "ecc inject" command shown above. The inject command
> takes a mask that is XORed with the proper data, eg "ecc
> inject low 0x5"
> would result in data bits 0 and 2 always being swapped resulting in
> multibit errors.
IIRC, 85xx cache is enabled, so when we do the ecc error inject test,
What will happen before disable ecc error inject?
I-fetch may get wrong instruction?
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 0:38 ` Liu Dave-R63238
@ 2009-11-10 0:42 ` Liu Dave-R63238
2009-11-10 0:46 ` Liu Dave-R63238
2009-11-10 1:01 ` Peter Tyser
0 siblings, 2 replies; 24+ messages in thread
From: Liu Dave-R63238 @ 2009-11-10 0:42 UTC (permalink / raw)
To: u-boot
> IIRC, 85xx cache is enabled, so when we do the ecc error inject test,
> What will happen before disable ecc error inject?
> I-fetch may get wrong instruction?
and ....
Because cache is enabled, data bus assume 64 bits (it is normal case).
The DDR bus will have 4-beat burst. So the error information will be
the last beat triggered, or multi-bit error at first beat....., or..
It is really complex.....
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 0:42 ` Liu Dave-R63238
@ 2009-11-10 0:46 ` Liu Dave-R63238
2009-11-10 1:01 ` Peter Tyser
1 sibling, 0 replies; 24+ messages in thread
From: Liu Dave-R63238 @ 2009-11-10 0:46 UTC (permalink / raw)
To: u-boot
> > IIRC, 85xx cache is enabled, so when we do the ecc error
> inject test,
> > What will happen before disable ecc error inject?
> > I-fetch may get wrong instruction?
>
> and ....
> Because cache is enabled, data bus assume 64 bits (it is normal case).
> The DDR bus will have 4-beat burst. So the error information will be
> the last beat triggered, or multi-bit error at first beat....., or..
> It is really complex.....
BTW, 83xx are using the d-cache inhibited...
The ecc test code really has some tricks, eg: must interrupt disable
context,
var should be put in the registers....
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 0:42 ` Liu Dave-R63238
2009-11-10 0:46 ` Liu Dave-R63238
@ 2009-11-10 1:01 ` Peter Tyser
2009-11-10 1:08 ` Liu Dave-R63238
1 sibling, 1 reply; 24+ messages in thread
From: Peter Tyser @ 2009-11-10 1:01 UTC (permalink / raw)
To: u-boot
On Tue, 2009-11-10 at 08:42 +0800, Liu Dave-R63238 wrote:
> > IIRC, 85xx cache is enabled, so when we do the ecc error inject test,
> > What will happen before disable ecc error inject?
> > I-fetch may get wrong instruction?
If you're injecting multibit errors, yes, things could break down, much
like a real multibit error.
> and ....
> Because cache is enabled, data bus assume 64 bits (it is normal case).
> The DDR bus will have 4-beat burst. So the error information will be
> the last beat triggered, or multi-bit error at first beat....., or..
> It is really complex.....
I believe all 4 beats would have the ecc error injected.
In my opinion, the error reporting functionality of the ECC code is much
more important than error injection. Other than testing code during
development, when do you inject errors? ECC detection and reporting is
useful day-to-day, in the field, during manufacturing tests, etc so
that's where the emphasis of this patch is focussed.
Best,
Peter
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 1:01 ` Peter Tyser
@ 2009-11-10 1:08 ` Liu Dave-R63238
2009-11-10 1:20 ` Peter Tyser
0 siblings, 1 reply; 24+ messages in thread
From: Liu Dave-R63238 @ 2009-11-10 1:08 UTC (permalink / raw)
To: u-boot
> On Tue, 2009-11-10 at 08:42 +0800, Liu Dave-R63238 wrote:
> > > IIRC, 85xx cache is enabled, so when we do the ecc error inject
> > > test, What will happen before disable ecc error inject?
> > > I-fetch may get wrong instruction?
>
> If you're injecting multibit errors, yes, things could break
> down, much like a real multibit error.
IIRC, 83xx ECC code will NOT break down when we inject multibit error.
The code will go on, u-boot also go on...
> > and ....
> > Because cache is enabled, data bus assume 64 bits (it is
> normal case).
> > The DDR bus will have 4-beat burst. So the error
> information will be
> > the last beat triggered, or multi-bit error at first beat....., or..
> > It is really complex.....
>
> I believe all 4 beats would have the ecc error injected.
>
> In my opinion, the error reporting functionality of the ECC
> code is much more important than error injection. Other than
> testing code during development, when do you inject errors?
> ECC detection and reporting is useful day-to-day, in the
> field, during manufacturing tests, etc so that's where the
> emphasis of this patch is focussed.
83xx ECC code also has good ECC error reporting functionality,
IIRC, type ecc status...
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 1:08 ` Liu Dave-R63238
@ 2009-11-10 1:20 ` Peter Tyser
2009-11-10 2:15 ` Ira W. Snyder
0 siblings, 1 reply; 24+ messages in thread
From: Peter Tyser @ 2009-11-10 1:20 UTC (permalink / raw)
To: u-boot
On Tue, 2009-11-10 at 09:08 +0800, Liu Dave-R63238 wrote:
> > On Tue, 2009-11-10 at 08:42 +0800, Liu Dave-R63238 wrote:
> > > > IIRC, 85xx cache is enabled, so when we do the ecc error inject
> > > > test, What will happen before disable ecc error inject?
> > > > I-fetch may get wrong instruction?
> >
> > If you're injecting multibit errors, yes, things could break
> > down, much like a real multibit error.
>
> IIRC, 83xx ECC code will NOT break down when we inject multibit error.
> The code will go on, u-boot also go on...
What is the benefit of having such a high level of control over error
injection? When do people use this feature? How often do they use it?
> > > and ....
> > > Because cache is enabled, data bus assume 64 bits (it is
> > normal case).
> > > The DDR bus will have 4-beat burst. So the error
> > information will be
> > > the last beat triggered, or multi-bit error at first beat....., or..
> > > It is really complex.....
> >
> > I believe all 4 beats would have the ecc error injected.
> >
> > In my opinion, the error reporting functionality of the ECC
> > code is much more important than error injection. Other than
> > testing code during development, when do you inject errors?
> > ECC detection and reporting is useful day-to-day, in the
> > field, during manufacturing tests, etc so that's where the
> > emphasis of this patch is focussed.
>
> 83xx ECC code also has good ECC error reporting functionality,
> IIRC, type ecc status...
I believe the ecc status command basically just did a register dump of
the ECC registers. In my opinion, the output was overly verbose and not
that useful. The patch I submitted attempts to *decode* the register
dump so Joe User can figure out what's really wrong with their board.
Best,
Peter
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 1:20 ` Peter Tyser
@ 2009-11-10 2:15 ` Ira W. Snyder
2009-11-10 3:07 ` Peter Tyser
0 siblings, 1 reply; 24+ messages in thread
From: Ira W. Snyder @ 2009-11-10 2:15 UTC (permalink / raw)
To: u-boot
On Mon, Nov 09, 2009 at 07:20:26PM -0600, Peter Tyser wrote:
> On Tue, 2009-11-10 at 09:08 +0800, Liu Dave-R63238 wrote:
> > > On Tue, 2009-11-10 at 08:42 +0800, Liu Dave-R63238 wrote:
> > > > > IIRC, 85xx cache is enabled, so when we do the ecc error inject
> > > > > test, What will happen before disable ecc error inject?
> > > > > I-fetch may get wrong instruction?
> > >
> > > If you're injecting multibit errors, yes, things could break
> > > down, much like a real multibit error.
> >
> > IIRC, 83xx ECC code will NOT break down when we inject multibit error.
> > The code will go on, u-boot also go on...
>
> What is the benefit of having such a high level of control over error
> injection? When do people use this feature? How often do they use it?
>
I used the ECC error injection code when adding ECC support on our
board, to verify that ECC was actually enabled and reporting errors. I
found it extremely useful at the time, though I haven't used it since.
> > > > and ....
> > > > Because cache is enabled, data bus assume 64 bits (it is
> > > normal case).
> > > > The DDR bus will have 4-beat burst. So the error
> > > information will be
> > > > the last beat triggered, or multi-bit error at first beat....., or..
> > > > It is really complex.....
> > >
> > > I believe all 4 beats would have the ecc error injected.
> > >
> > > In my opinion, the error reporting functionality of the ECC
> > > code is much more important than error injection. Other than
> > > testing code during development, when do you inject errors?
> > > ECC detection and reporting is useful day-to-day, in the
> > > field, during manufacturing tests, etc so that's where the
> > > emphasis of this patch is focussed.
> >
> > 83xx ECC code also has good ECC error reporting functionality,
> > IIRC, type ecc status...
>
> I believe the ecc status command basically just did a register dump of
> the ECC registers. In my opinion, the output was overly verbose and not
> that useful. The patch I submitted attempts to *decode* the register
> dump so Joe User can figure out what's really wrong with their board.
>
I haven't looked at your code. When I was running the old ecc command, I
had the 83xx reference manual open to decode the command's output, IIRC.
PS - I'm happy to test stuff on 83xx, I'll try and find time to test
this patch series tomorrow.
Ira
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 2:15 ` Ira W. Snyder
@ 2009-11-10 3:07 ` Peter Tyser
2009-11-10 16:51 ` Ira W. Snyder
0 siblings, 1 reply; 24+ messages in thread
From: Peter Tyser @ 2009-11-10 3:07 UTC (permalink / raw)
To: u-boot
Hi Ira,
On Mon, 2009-11-09 at 18:15 -0800, Ira W. Snyder wrote:
> On Mon, Nov 09, 2009 at 07:20:26PM -0600, Peter Tyser wrote:
> > On Tue, 2009-11-10 at 09:08 +0800, Liu Dave-R63238 wrote:
> > > > On Tue, 2009-11-10 at 08:42 +0800, Liu Dave-R63238 wrote:
> > > > > > IIRC, 85xx cache is enabled, so when we do the ecc error inject
> > > > > > test, What will happen before disable ecc error inject?
> > > > > > I-fetch may get wrong instruction?
> > > >
> > > > If you're injecting multibit errors, yes, things could break
> > > > down, much like a real multibit error.
> > >
> > > IIRC, 83xx ECC code will NOT break down when we inject multibit error.
> > > The code will go on, u-boot also go on...
> >
> > What is the benefit of having such a high level of control over error
> > injection? When do people use this feature? How often do they use it?
> >
>
> I used the ECC error injection code when adding ECC support on our
> board, to verify that ECC was actually enabled and reporting errors. I
> found it extremely useful at the time, though I haven't used it since.
I had the same usage pattern as you. I used the "ecc inject" command
for some testing, but I don't plan using it again unless I update the
ECC code again. The injecting feature of this patch isn't great, but I
personally think its sufficient, at least on 85xx and 86xx. I was
pretty easily able to simulate single and double bit errors on both
platforms. I'll be curious to hear how it works on 83xx...
> > > > > and ....
> > > > > Because cache is enabled, data bus assume 64 bits (it is
> > > > normal case).
> > > > > The DDR bus will have 4-beat burst. So the error
> > > > information will be
> > > > > the last beat triggered, or multi-bit error at first beat....., or..
> > > > > It is really complex.....
> > > >
> > > > I believe all 4 beats would have the ecc error injected.
> > > >
> > > > In my opinion, the error reporting functionality of the ECC
> > > > code is much more important than error injection. Other than
> > > > testing code during development, when do you inject errors?
> > > > ECC detection and reporting is useful day-to-day, in the
> > > > field, during manufacturing tests, etc so that's where the
> > > > emphasis of this patch is focussed.
> > >
> > > 83xx ECC code also has good ECC error reporting functionality,
> > > IIRC, type ecc status...
> >
> > I believe the ecc status command basically just did a register dump of
> > the ECC registers. In my opinion, the output was overly verbose and not
> > that useful. The patch I submitted attempts to *decode* the register
> > dump so Joe User can figure out what's really wrong with their board.
> >
>
> I haven't looked at your code. When I was running the old ecc command, I
> had the 83xx reference manual open to decode the command's output, IIRC.
>
> PS - I'm happy to test stuff on 83xx, I'll try and find time to test
> this patch series tomorrow.
Thanks, its much appreciated.
Peter
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 3:07 ` Peter Tyser
@ 2009-11-10 16:51 ` Ira W. Snyder
2009-11-10 17:36 ` Peter Tyser
0 siblings, 1 reply; 24+ messages in thread
From: Ira W. Snyder @ 2009-11-10 16:51 UTC (permalink / raw)
To: u-boot
On Mon, Nov 09, 2009 at 09:07:25PM -0600, Peter Tyser wrote:
[ big snip ]
> >
> > I haven't looked at your code. When I was running the old ecc command, I
> > had the 83xx reference manual open to decode the command's output, IIRC.
> >
> > PS - I'm happy to test stuff on 83xx, I'll try and find time to test
> > this patch series tomorrow.
>
> Thanks, its much appreciated.
>
Ok, here are my results, this is on a 8349EMDS-derived board. My
8349EMDS eval board doesn't have ECC memory.
1) It might be nice to have something to print the current injection
registers. It is not a big deal, anyone using this should be an expert
anyway.
2) ecc inject off didn't seem to work, see the following capture:
=> ecc info
No ECC errors have occurred
=> ecc inject low 0x1
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0ff7ae40
Data: 0x0fffdf9c_0ff7aed1 ECC: 0x81
Expect: 0x0fffdf9c_0ff7aed0 ECC: 0x81
Net: DATA0
Syndrome: 0x3b
Single-Bit errors: 0x1e
Attrib: 0x01002001
Detect: 0x80000004 (MME, SBE)
=> ecc inject off
# Ok, now error injection is off, I still expect some errors to be
# present in the error registers
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0ff7ae1c
Data: 0x0fffdf9c_0ff7d2a1 ECC: 0xe4
Expect: 0x0fffdf9c_0ff7d2a0 ECC: 0xe4
Net: DATA0
Syndrome: 0x3b
Single-Bit errors: 0xd1
Attrib: 0x01003001
Detect: 0x80000004 (MME, SBE)
# And there was the error. Now, I don't expect any more errors to
# be present, after all, injection is disabled.
#
# But there is one! Why?
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0fff8a0c
Data: 0x0fff8a00_0fff8a01 ECC: 0xff
Expect: 0x0fff8a00_0fff8a00 ECC: 0xff
Net: DATA0
Syndrome: 0x3b
Single-Bit errors: 0x04
Attrib: 0x01003001
Detect: 0x00000000
=>
# Note that I keep seeing ecc errors until I run the command:
# ecc inject low 0
Here is another trace showing "interesting" behavior:
=> ecc info
No ECC errors have occurred
=> ecc inject high 1
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0ff7ae40
Data: 0x0fffdf9d_0ff7aed0 ECC: 0x81
Expect: 0x0fffdf9c_0ff7aed0 ECC: 0x81
Net: DATA32
Syndrome: 0xce
Single-Bit errors: 0xd8
Attrib: 0x01002001
Detect: 0x80000004 (MME, SBE)
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0fff89c4
Data: 0x0fff89b9_0ff7d268 ECC: 0x02
Expect: 0x0fff89b8_0ff7d268 ECC: 0x02
Net: DATA32
Syndrome: 0xce
Single-Bit errors: 0xea
Attrib: 0x01003001
Detect: 0x80000004 (MME, SBE)
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0ff7d2e8
Data: 0x00000001_0ff7d300 ECC: 0x99
Expect: 0x00000000_0ff7d300 ECC: 0x99
Net: DATA32
Syndrome: 0xce
Single-Bit errors: 0x30
Attrib: 0x01002001
Detect: 0x80000004 (MME, SBE)
=> ecc inject high 0
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0ff7d2e8
Data: 0x00000001_0ff7d300 ECC: 0x99
Expect: 0x00000000_0ff7d300 ECC: 0x99
Net: DATA32
Syndrome: 0xce
Single-Bit errors: 0x81
Attrib: 0x01002001
Detect: 0x80000004 (MME, SBE)
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0fff8a0c
Data: 0x0fff8a01_0fff8a00 ECC: 0xff
Expect: 0x0fff8a00_0fff8a00 ECC: 0xff
Net: DATA32
Syndrome: 0xce
Single-Bit errors: 0x04
Attrib: 0x01003001
Detect: 0x00000000
=> ecc info
No ECC errors have occurred
=> ecc info
No ECC errors have occurred
# Why did it take two runs of ecc info to clear all of the errors?
Other than the above strangeness, everything is working great on my 83xx
board. I think the new output is pretty nice. It serves my purposes
equally well to the old code.
Ira
^ permalink raw reply [flat|nested] 24+ messages in thread* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 16:51 ` Ira W. Snyder
@ 2009-11-10 17:36 ` Peter Tyser
2009-11-10 17:53 ` Ira W. Snyder
0 siblings, 1 reply; 24+ messages in thread
From: Peter Tyser @ 2009-11-10 17:36 UTC (permalink / raw)
To: u-boot
> Ok, here are my results, this is on a 8349EMDS-derived board. My
> 8349EMDS eval board doesn't have ECC memory.
>
> 1) It might be nice to have something to print the current injection
> registers. It is not a big deal, anyone using this should be an expert
> anyway.
Thanks for the feedback. I can add a printing of the current injection
values when "ecc inject" is ran if others would like.
> 2) ecc inject off didn't seem to work, see the following capture:
>
> => ecc info
> No ECC errors have occurred
> => ecc inject low 0x1
> => ecc info
>
> WARNING: ECC error in DDR Controller 0
> Addr: 0x0_0ff7ae40
> Data: 0x0fffdf9c_0ff7aed1 ECC: 0x81
> Expect: 0x0fffdf9c_0ff7aed0 ECC: 0x81
> Net: DATA0
> Syndrome: 0x3b
> Single-Bit errors: 0x1e
> Attrib: 0x01002001
> Detect: 0x80000004 (MME, SBE)
>
> => ecc inject off
>
> # Ok, now error injection is off, I still expect some errors to be
> # present in the error registers
>
> => ecc info
>
> WARNING: ECC error in DDR Controller 0
> Addr: 0x0_0ff7ae1c
> Data: 0x0fffdf9c_0ff7d2a1 ECC: 0xe4
> Expect: 0x0fffdf9c_0ff7d2a0 ECC: 0xe4
> Net: DATA0
> Syndrome: 0x3b
> Single-Bit errors: 0xd1
> Attrib: 0x01003001
> Detect: 0x80000004 (MME, SBE)
>
> # And there was the error. Now, I don't expect any more errors to
> # be present, after all, injection is disabled.
> #
> # But there is one! Why?
I believe what's happening is:
1. You turn error injection on
2. Every time you perform a DRAM write, the value written has an ECC
error
3. You write to DRAM lots of times, in lots of locations
4. You turn error injection off
5. There are still lots of ECC errors residing in DRAM that you discover
later when you read from "corrupted" memory locations
So in theory, unless you scrub your memory, you might uncover lots more
ECC errors later.
As an easily reproducible example try:
> ecc inject low 1; mw.l 0x100000 0xbeefba11 0x800000; ecc inject off
> ecc info
> ecc info
> md 0x100000
> ecc info
> ecc info
> md 0x200000
...
The majority of the above ecc errors could be cleared by running the
following command with ecc injection off:
mw.l 0x100000 0xbeefba11 0x800000
> => ecc info
>
> WARNING: ECC error in DDR Controller 0
> Addr: 0x0_0fff8a0c
> Data: 0x0fff8a00_0fff8a01 ECC: 0xff
> Expect: 0x0fff8a00_0fff8a00 ECC: 0xff
> Net: DATA0
> Syndrome: 0x3b
> Single-Bit errors: 0x04
> Attrib: 0x01003001
> Detect: 0x00000000
> =>
>
> # Note that I keep seeing ecc errors until I run the command:
> # ecc inject low 0
Hmm... "ecc inject off" should have the same effect as "ecc inject low
0". Is there a chance some of the ECC errors still remaining in DRAM
are the culprit?
> # Why did it take two runs of ecc info to clear all of the errors?
This is probably the same issue as above - lots errors are injected and
there's no saying when exactly they'll turn up.
> Other than the above strangeness, everything is working great on my 83xx
> board. I think the new output is pretty nice. It serves my purposes
> equally well to the old code.
Thanks for trying the changes out,
Peter
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support
2009-11-10 17:36 ` Peter Tyser
@ 2009-11-10 17:53 ` Ira W. Snyder
0 siblings, 0 replies; 24+ messages in thread
From: Ira W. Snyder @ 2009-11-10 17:53 UTC (permalink / raw)
To: u-boot
On Tue, Nov 10, 2009 at 11:36:44AM -0600, Peter Tyser wrote:
> > Ok, here are my results, this is on a 8349EMDS-derived board. My
> > 8349EMDS eval board doesn't have ECC memory.
> >
> > 1) It might be nice to have something to print the current injection
> > registers. It is not a big deal, anyone using this should be an expert
> > anyway.
>
> Thanks for the feedback. I can add a printing of the current injection
> values when "ecc inject" is ran if others would like.
>
> > 2) ecc inject off didn't seem to work, see the following capture:
> >
> > => ecc info
> > No ECC errors have occurred
> > => ecc inject low 0x1
> > => ecc info
> >
> > WARNING: ECC error in DDR Controller 0
> > Addr: 0x0_0ff7ae40
> > Data: 0x0fffdf9c_0ff7aed1 ECC: 0x81
> > Expect: 0x0fffdf9c_0ff7aed0 ECC: 0x81
> > Net: DATA0
> > Syndrome: 0x3b
> > Single-Bit errors: 0x1e
> > Attrib: 0x01002001
> > Detect: 0x80000004 (MME, SBE)
> >
> > => ecc inject off
> >
> > # Ok, now error injection is off, I still expect some errors to be
> > # present in the error registers
> >
> > => ecc info
> >
> > WARNING: ECC error in DDR Controller 0
> > Addr: 0x0_0ff7ae1c
> > Data: 0x0fffdf9c_0ff7d2a1 ECC: 0xe4
> > Expect: 0x0fffdf9c_0ff7d2a0 ECC: 0xe4
> > Net: DATA0
> > Syndrome: 0x3b
> > Single-Bit errors: 0xd1
> > Attrib: 0x01003001
> > Detect: 0x80000004 (MME, SBE)
> >
> > # And there was the error. Now, I don't expect any more errors to
> > # be present, after all, injection is disabled.
> > #
> > # But there is one! Why?
>
> I believe what's happening is:
> 1. You turn error injection on
> 2. Every time you perform a DRAM write, the value written has an ECC
> error
> 3. You write to DRAM lots of times, in lots of locations
> 4. You turn error injection off
> 5. There are still lots of ECC errors residing in DRAM that you discover
> later when you read from "corrupted" memory locations
>
> So in theory, unless you scrub your memory, you might uncover lots more
> ECC errors later.
>
> As an easily reproducible example try:
> > ecc inject low 1; mw.l 0x100000 0xbeefba11 0x800000; ecc inject off
> > ecc info
> > ecc info
> > md 0x100000
> > ecc info
> > ecc info
> > md 0x200000
> ...
>
> The majority of the above ecc errors could be cleared by running the
> following command with ecc injection off:
> mw.l 0x100000 0xbeefba11 0x800000
>
>
> > => ecc info
> >
> > WARNING: ECC error in DDR Controller 0
> > Addr: 0x0_0fff8a0c
> > Data: 0x0fff8a00_0fff8a01 ECC: 0xff
> > Expect: 0x0fff8a00_0fff8a00 ECC: 0xff
> > Net: DATA0
> > Syndrome: 0x3b
> > Single-Bit errors: 0x04
> > Attrib: 0x01003001
> > Detect: 0x00000000
> > =>
> >
> > # Note that I keep seeing ecc errors until I run the command:
> > # ecc inject low 0
>
> Hmm... "ecc inject off" should have the same effect as "ecc inject low
> 0". Is there a chance some of the ECC errors still remaining in DRAM
> are the culprit?
>
> > # Why did it take two runs of ecc info to clear all of the errors?
>
> This is probably the same issue as above - lots errors are injected and
> there's no saying when exactly they'll turn up.
>
> > Other than the above strangeness, everything is working great on my 83xx
> > board. I think the new output is pretty nice. It serves my purposes
> > equally well to the old code.
>
> Thanks for trying the changes out,
Ok, this makes perfect sense. I didn't think about the possibility of
latent memory errors. :)
Here is a run using your instructions above. Keeping the possibility of
latent memory errors in mind, the behavior seems correct to me. You're
free to add my Tested-by if you'd like.
=> ecc inject low 1
=> mw.l 0x100000 0xbeefba11 0x800000
=> ecc inject off
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0ff7ae40
Data: 0x0fffdf9c_0ff7aed1 ECC: 0x81
Expect: 0x0fffdf9c_0ff7aed0 ECC: 0x81
Net: DATA0
Syndrome: 0x3b
Single-Bit errors: 0x56
Attrib: 0x01002001
Detect: 0x80000004 (MME, SBE)
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0ff7ad08
Data: 0x0ffd594c_0000087f ECC: 0x91
Expect: 0x0ffd594c_0000087e ECC: 0x91
Net: DATA0
Syndrome: 0x3b
Single-Bit errors: 0x01
Attrib: 0x01003001
Detect: 0x00000000
=> ecc info
No ECC errors have occurred
=> ecc info
No ECC errors have occurred
=> ecc info
No ECC errors have occurred
=> md 0x100000 10
00100000: beefba11 beefba11 beefba11 beefba11 ................
00100010: beefba11 beefba11 beefba11 beefba11 ................
00100020: beefba11 beefba11 beefba11 beefba11 ................
00100030: beefba11 beefba11 beefba11 beefba11 ................
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0010003c
Data: 0xbeefba11_beefba10 ECC: 0x7b
Expect: 0xbeefba11_beefba11 ECC: 0x7b
Net: DATA0
Syndrome: 0x3b
Single-Bit errors: 0x13
Attrib: 0x01002001
Detect: 0x00000000
=> ecc info
No ECC errors have occurred
=> md 0x200000 10
00200000: beefba11 beefba11 beefba11 beefba11 ................
00200010: beefba11 beefba11 beefba11 beefba11 ................
00200020: beefba11 beefba11 beefba11 beefba11 ................
00200030: beefba11 beefba11 beefba11 beefba11 ................
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_0020003c
Data: 0xbeefba11_beefba10 ECC: 0x7b
Expect: 0xbeefba11_beefba11 ECC: 0x7b
Net: DATA0
Syndrome: 0x3b
Single-Bit errors: 0x10
Attrib: 0x01002001
Detect: 0x00000000
=> ecc info
No ECC errors have occurred
=> mw.l 0x100000 0xbeefba11 0x800000
=> ecc info
WARNING: ECC error in DDR Controller 0
Addr: 0x0_001007c8
Data: 0xbeefba11_beefba10 ECC: 0x7b
Expect: 0xbeefba11_beefba11 ECC: 0x7b
Net: DATA0
Syndrome: 0x3b
Single-Bit errors: 0x06
Attrib: 0x01003001
Detect: 0x80000004 (MME, SBE)
=> ecc info
No ECC errors have occurred
=> ecc info
No ECC errors have occurred
Ira
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 4/7] 83xx: Migrate CONFIG_DDR_ECC_CMD to CONFIG_EDAC_FSL_ECC
2009-11-09 23:37 [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update Peter Tyser
` (2 preceding siblings ...)
2009-11-09 23:37 ` [U-Boot] [PATCH 3/7] 83xx/85xx/86xx: Add ECC support Peter Tyser
@ 2009-11-09 23:37 ` Peter Tyser
2009-11-10 0:51 ` [U-Boot] [PATCH 4/7] 83xx: Migrate CONFIG_DDR_ECC_CMD toCONFIG_EDAC_FSL_ECC Liu Dave-R63238
2009-11-09 23:37 ` [U-Boot] [PATCH 5/7] Add check for ECC errors during SDRAM POST and mtest Peter Tyser
` (3 subsequent siblings)
7 siblings, 1 reply; 24+ messages in thread
From: Peter Tyser @ 2009-11-09 23:37 UTC (permalink / raw)
To: u-boot
Update 83xx boards to use the same ECC driver that the 85xx and 86xx
boards currently use. The common 83xx/85xx/86xx ECC driver has
fewer options, but better error reporting.
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
---
cpu/mpc83xx/Makefile | 1 -
cpu/mpc83xx/ecc.c | 390 -----------------------------------------
include/configs/MPC8349EMDS.h | 2 +-
include/configs/MPC8360EMDS.h | 2 +-
include/configs/MPC8360ERDK.h | 2 +-
include/configs/MPC837XEMDS.h | 2 +-
include/configs/MPC837XERDB.h | 2 +-
include/configs/sbc8349.h | 2 +-
include/configs/vme8349.h | 2 +-
9 files changed, 7 insertions(+), 398 deletions(-)
delete mode 100644 cpu/mpc83xx/ecc.c
diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile
index 15e2c18..8fda557 100644
--- a/cpu/mpc83xx/Makefile
+++ b/cpu/mpc83xx/Makefile
@@ -35,7 +35,6 @@ COBJS-y += cpu_init.o
COBJS-y += speed.o
COBJS-y += interrupts.o
COBJS-y += spd_sdram.o
-COBJS-y += ecc.o
COBJS-$(CONFIG_QE) += qe_io.o
COBJS-$(CONFIG_FSL_SERDES) += serdes.o
COBJS-$(CONFIG_PCI) += pci.o
diff --git a/cpu/mpc83xx/ecc.c b/cpu/mpc83xx/ecc.c
deleted file mode 100644
index f3942b4..0000000
--- a/cpu/mpc83xx/ecc.c
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2007 Freescale Semiconductor, Inc.
- *
- * Dave Liu <daveliu@freescale.com>
- * based on the contribution of Marian Balakowicz <m8@semihalf.com>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- */
-
-#include <common.h>
-#include <mpc83xx.h>
-#include <command.h>
-
-#if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
-void ecc_print_status(void)
-{
- volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
- volatile ddr83xx_t *ddr = &immap->ddr;
-
- printf("\nECC mode: %s\n\n",
- (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
-
- /* Interrupts */
- printf("Memory Error Interrupt Enable:\n");
- printf(" Multiple-Bit Error Interrupt Enable: %d\n",
- (ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0);
- printf(" Single-Bit Error Interrupt Enable: %d\n",
- (ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0);
- printf(" Memory Select Error Interrupt Enable: %d\n\n",
- (ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0);
-
- /* Error disable */
- printf("Memory Error Disable:\n");
- printf(" Multiple-Bit Error Disable: %d\n",
- (ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0);
- printf(" Sinle-Bit Error Disable: %d\n",
- (ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0);
- printf(" Memory Select Error Disable: %d\n\n",
- (ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0);
-
- /* Error injection */
- printf("Memory Data Path Error Injection Mask High/Low: %08x %08x\n",
- ddr->data_err_inject_hi, ddr->data_err_inject_lo);
-
- printf("Memory Data Path Error Injection Mask ECC:\n");
- printf(" ECC Mirror Byte: %d\n",
- (ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0);
- printf(" ECC Injection Enable: %d\n",
- (ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0);
- printf(" ECC Error Injection Mask: 0x%02x\n\n",
- ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM);
-
- /* SBE counter/threshold */
- printf("Memory Single-Bit Error Management (0..255):\n");
- printf(" Single-Bit Error Threshold: %d\n",
- (ddr->err_sbe & ECC_ERROR_MAN_SBET) >> ECC_ERROR_MAN_SBET_SHIFT);
- printf(" Single-Bit Error Counter: %d\n\n",
- (ddr->err_sbe & ECC_ERROR_MAN_SBEC) >> ECC_ERROR_MAN_SBEC_SHIFT);
-
- /* Error detect */
- printf("Memory Error Detect:\n");
- printf(" Multiple Memory Errors: %d\n",
- (ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0);
- printf(" Multiple-Bit Error: %d\n",
- (ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0);
- printf(" Single-Bit Error: %d\n",
- (ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0);
- printf(" Memory Select Error: %d\n\n",
- (ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0);
-
- /* Capture data */
- printf("Memory Error Address Capture: 0x%08x\n", ddr->capture_address);
- printf("Memory Data Path Read Capture High/Low: %08x %08x\n",
- ddr->capture_data_hi, ddr->capture_data_lo);
- printf("Memory Data Path Read Capture ECC: 0x%02x\n\n",
- ddr->capture_ecc & CAPTURE_ECC_ECE);
-
- printf("Memory Error Attributes Capture:\n");
- printf(" Data Beat Number: %d\n",
- (ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >>
- ECC_CAPT_ATTR_BNUM_SHIFT);
- printf(" Transaction Size: %d\n",
- (ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >>
- ECC_CAPT_ATTR_TSIZ_SHIFT);
- printf(" Transaction Source: %d\n",
- (ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >>
- ECC_CAPT_ATTR_TSRC_SHIFT);
- printf(" Transaction Type: %d\n",
- (ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >>
- ECC_CAPT_ATTR_TTYP_SHIFT);
- printf(" Error Information Valid: %d\n\n",
- ddr->capture_attributes & ECC_CAPT_ATTR_VLD);
-}
-
-int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
-{
- volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
- volatile ddr83xx_t *ddr = &immap->ddr;
- volatile u32 val;
- u64 *addr;
- u32 count;
- register u64 *i;
- u32 ret[2];
- u32 pattern[2];
- u32 writeback[2];
-
- /* The pattern is written into memory to generate error */
- pattern[0] = 0xfedcba98UL;
- pattern[1] = 0x76543210UL;
-
- /* After injecting error, re-initialize the memory with the value */
- writeback[0] = 0x01234567UL;
- writeback[1] = 0x89abcdefUL;
-
- if (argc > 4) {
- cmd_usage(cmdtp);
- return 1;
- }
-
- if (argc == 2) {
- if (strcmp(argv[1], "status") == 0) {
- ecc_print_status();
- return 0;
- } else if (strcmp(argv[1], "captureclear") == 0) {
- ddr->capture_address = 0;
- ddr->capture_data_hi = 0;
- ddr->capture_data_lo = 0;
- ddr->capture_ecc = 0;
- ddr->capture_attributes = 0;
- return 0;
- }
- }
- if (argc == 3) {
- if (strcmp(argv[1], "sbecnt") == 0) {
- val = simple_strtoul(argv[2], NULL, 10);
- if (val > 255) {
- printf("Incorrect Counter value, "
- "should be 0..255\n");
- return 1;
- }
-
- val = (val << ECC_ERROR_MAN_SBEC_SHIFT);
- val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET);
-
- ddr->err_sbe = val;
- return 0;
- } else if (strcmp(argv[1], "sbethr") == 0) {
- val = simple_strtoul(argv[2], NULL, 10);
- if (val > 255) {
- printf("Incorrect Counter value, "
- "should be 0..255\n");
- return 1;
- }
-
- val = (val << ECC_ERROR_MAN_SBET_SHIFT);
- val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC);
-
- ddr->err_sbe = val;
- return 0;
- } else if (strcmp(argv[1], "errdisable") == 0) {
- val = ddr->err_disable;
-
- if (strcmp(argv[2], "+sbe") == 0) {
- val |= ECC_ERROR_DISABLE_SBED;
- } else if (strcmp(argv[2], "+mbe") == 0) {
- val |= ECC_ERROR_DISABLE_MBED;
- } else if (strcmp(argv[2], "+mse") == 0) {
- val |= ECC_ERROR_DISABLE_MSED;
- } else if (strcmp(argv[2], "+all") == 0) {
- val |= (ECC_ERROR_DISABLE_SBED |
- ECC_ERROR_DISABLE_MBED |
- ECC_ERROR_DISABLE_MSED);
- } else if (strcmp(argv[2], "-sbe") == 0) {
- val &= ~ECC_ERROR_DISABLE_SBED;
- } else if (strcmp(argv[2], "-mbe") == 0) {
- val &= ~ECC_ERROR_DISABLE_MBED;
- } else if (strcmp(argv[2], "-mse") == 0) {
- val &= ~ECC_ERROR_DISABLE_MSED;
- } else if (strcmp(argv[2], "-all") == 0) {
- val &= ~(ECC_ERROR_DISABLE_SBED |
- ECC_ERROR_DISABLE_MBED |
- ECC_ERROR_DISABLE_MSED);
- } else {
- printf("Incorrect err_disable field\n");
- return 1;
- }
-
- ddr->err_disable = val;
- __asm__ __volatile__("sync");
- __asm__ __volatile__("isync");
- return 0;
- } else if (strcmp(argv[1], "errdetectclr") == 0) {
- val = ddr->err_detect;
-
- if (strcmp(argv[2], "mme") == 0) {
- val |= ECC_ERROR_DETECT_MME;
- } else if (strcmp(argv[2], "sbe") == 0) {
- val |= ECC_ERROR_DETECT_SBE;
- } else if (strcmp(argv[2], "mbe") == 0) {
- val |= ECC_ERROR_DETECT_MBE;
- } else if (strcmp(argv[2], "mse") == 0) {
- val |= ECC_ERROR_DETECT_MSE;
- } else if (strcmp(argv[2], "all") == 0) {
- val |= (ECC_ERROR_DETECT_MME |
- ECC_ERROR_DETECT_MBE |
- ECC_ERROR_DETECT_SBE |
- ECC_ERROR_DETECT_MSE);
- } else {
- printf("Incorrect err_detect field\n");
- return 1;
- }
-
- ddr->err_detect = val;
- return 0;
- } else if (strcmp(argv[1], "injectdatahi") == 0) {
- val = simple_strtoul(argv[2], NULL, 16);
-
- ddr->data_err_inject_hi = val;
- return 0;
- } else if (strcmp(argv[1], "injectdatalo") == 0) {
- val = simple_strtoul(argv[2], NULL, 16);
-
- ddr->data_err_inject_lo = val;
- return 0;
- } else if (strcmp(argv[1], "injectecc") == 0) {
- val = simple_strtoul(argv[2], NULL, 16);
- if (val > 0xff) {
- printf("Incorrect ECC inject mask, "
- "should be 0x00..0xff\n");
- return 1;
- }
- val |= (ddr->ecc_err_inject & ~ECC_ERR_INJECT_EEIM);
-
- ddr->ecc_err_inject = val;
- return 0;
- } else if (strcmp(argv[1], "inject") == 0) {
- val = ddr->ecc_err_inject;
-
- if (strcmp(argv[2], "en") == 0)
- val |= ECC_ERR_INJECT_EIEN;
- else if (strcmp(argv[2], "dis") == 0)
- val &= ~ECC_ERR_INJECT_EIEN;
- else
- printf("Incorrect command\n");
-
- ddr->ecc_err_inject = val;
- __asm__ __volatile__("sync");
- __asm__ __volatile__("isync");
- return 0;
- } else if (strcmp(argv[1], "mirror") == 0) {
- val = ddr->ecc_err_inject;
-
- if (strcmp(argv[2], "en") == 0)
- val |= ECC_ERR_INJECT_EMB;
- else if (strcmp(argv[2], "dis") == 0)
- val &= ~ECC_ERR_INJECT_EMB;
- else
- printf("Incorrect command\n");
-
- ddr->ecc_err_inject = val;
- return 0;
- }
- }
- if (argc == 4) {
- if (strcmp(argv[1], "testdw") == 0) {
- addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
- count = simple_strtoul(argv[3], NULL, 16);
-
- if ((u32) addr % 8) {
- printf("Address not alligned on "
- "double word boundary\n");
- return 1;
- }
- disable_interrupts();
-
- for (i = addr; i < addr + count; i++) {
-
- /* enable injects */
- ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
- __asm__ __volatile__("sync");
- __asm__ __volatile__("isync");
-
- /* write memory location injecting errors */
- ppcDWstore((u32 *) i, pattern);
- __asm__ __volatile__("sync");
-
- /* disable injects */
- ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
- __asm__ __volatile__("sync");
- __asm__ __volatile__("isync");
-
- /* read data, this generates ECC error */
- ppcDWload((u32 *) i, ret);
- __asm__ __volatile__("sync");
-
- /* re-initialize memory, double word write the location again,
- * generates new ECC code this time */
- ppcDWstore((u32 *) i, writeback);
- __asm__ __volatile__("sync");
- }
- enable_interrupts();
- return 0;
- }
- if (strcmp(argv[1], "testword") == 0) {
- addr = (u64 *) simple_strtoul(argv[2], NULL, 16);
- count = simple_strtoul(argv[3], NULL, 16);
-
- if ((u32) addr % 8) {
- printf("Address not alligned on "
- "double word boundary\n");
- return 1;
- }
- disable_interrupts();
-
- for (i = addr; i < addr + count; i++) {
-
- /* enable injects */
- ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN;
- __asm__ __volatile__("sync");
- __asm__ __volatile__("isync");
-
- /* write memory location injecting errors */
- *(u32 *) i = 0xfedcba98UL;
- __asm__ __volatile__("sync");
-
- /* sub double word write,
- * bus will read-modify-write,
- * generates ECC error */
- *((u32 *) i + 1) = 0x76543210UL;
- __asm__ __volatile__("sync");
-
- /* disable injects */
- ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN;
- __asm__ __volatile__("sync");
- __asm__ __volatile__("isync");
-
- /* re-initialize memory,
- * double word write the location again,
- * generates new ECC code this time */
- ppcDWstore((u32 *) i, writeback);
- __asm__ __volatile__("sync");
- }
- enable_interrupts();
- return 0;
- }
- }
- cmd_usage(cmdtp);
- return 1;
-}
-
-U_BOOT_CMD(ecc, 4, 0, do_ecc,
- "support for DDR ECC features",
- "status - print out status info\n"
- "ecc captureclear - clear capture regs data\n"
- "ecc sbecnt <val> - set Single-Bit Error counter\n"
- "ecc sbethr <val> - set Single-Bit Threshold\n"
- "ecc errdisable <flag> - clear/set disable Memory Error Disable, flag:\n"
- " [-|+]sbe - Single-Bit Error\n"
- " [-|+]mbe - Multiple-Bit Error\n"
- " [-|+]mse - Memory Select Error\n"
- " [-|+]all - all errors\n"
- "ecc errdetectclr <flag> - clear Memory Error Detect, flag:\n"
- " mme - Multiple Memory Errors\n"
- " sbe - Single-Bit Error\n"
- " mbe - Multiple-Bit Error\n"
- " mse - Memory Select Error\n"
- " all - all errors\n"
- "ecc injectdatahi <hi> - set Memory Data Path Error Injection Mask High\n"
- "ecc injectdatalo <lo> - set Memory Data Path Error Injection Mask Low\n"
- "ecc injectecc <ecc> - set ECC Error Injection Mask\n"
- "ecc inject <en|dis> - enable/disable error injection\n"
- "ecc mirror <en|dis> - enable/disable mirror byte\n"
- "ecc testdw <addr> <cnt> - test mem region with double word access:\n"
- " - enables injects\n"
- " - writes pattern injecting errors with double word access\n"
- " - disables injects\n"
- " - reads pattern back with double word access, generates error\n"
- " - re-inits memory\n"
- "ecc testword <addr> <cnt> - test mem region with word access:\n"
- " - enables injects\n"
- " - writes pattern injecting errors with word access\n"
- " - writes pattern with word access, generates error\n"
- " - disables injects\n" " - re-inits memory");
-#endif
diff --git a/include/configs/MPC8349EMDS.h b/include/configs/MPC8349EMDS.h
index 6361c45..34fb59f 100644
--- a/include/configs/MPC8349EMDS.h
+++ b/include/configs/MPC8349EMDS.h
@@ -72,7 +72,7 @@
* DDR Setup
*/
#define CONFIG_DDR_ECC /* support DDR ECC function */
-#define CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */
+#define CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
#define CONFIG_SPD_EEPROM /* use SPD EEPROM for DDR setup*/
/*
diff --git a/include/configs/MPC8360EMDS.h b/include/configs/MPC8360EMDS.h
index 8520155..fc2d456 100644
--- a/include/configs/MPC8360EMDS.h
+++ b/include/configs/MPC8360EMDS.h
@@ -108,7 +108,7 @@
#define CONFIG_SYS_83XX_DDR_USES_CS0
#define CONFIG_DDR_ECC /* support DDR ECC function */
-#define CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */
+#define CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
/*
* DDRCDR - DDR Control Driver Register
diff --git a/include/configs/MPC8360ERDK.h b/include/configs/MPC8360ERDK.h
index 6cee78a..253c733 100644
--- a/include/configs/MPC8360ERDK.h
+++ b/include/configs/MPC8360ERDK.h
@@ -90,7 +90,7 @@
#define CONFIG_SYS_83XX_DDR_USES_CS0
#define CONFIG_DDR_ECC /* support DDR ECC function */
-#define CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */
+#define CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
/*
* DDRCDR - DDR Control Driver Register
diff --git a/include/configs/MPC837XEMDS.h b/include/configs/MPC837XEMDS.h
index abeb6a2..45d1fa6 100644
--- a/include/configs/MPC837XEMDS.h
+++ b/include/configs/MPC837XEMDS.h
@@ -129,7 +129,7 @@
#define CONFIG_SYS_DDRCDR_VALUE 0x80080001 /* ODT 150ohm on SoC */
#undef CONFIG_DDR_ECC /* support DDR ECC function */
-#undef CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */
+#undef CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
#define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */
#define CONFIG_NEVER_ASSERT_ODT_TO_CPU /* Never assert ODT to internal IOs */
diff --git a/include/configs/MPC837XERDB.h b/include/configs/MPC837XERDB.h
index 7ef92f7..cdde255 100644
--- a/include/configs/MPC837XERDB.h
+++ b/include/configs/MPC837XERDB.h
@@ -155,7 +155,7 @@
#define CONFIG_SYS_DDRCDR_VALUE (DDRCDR_DHC_EN | DDRCDR_ODT | DDRCDR_Q_DRN)
#undef CONFIG_DDR_ECC /* support DDR ECC function */
-#undef CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */
+#undef CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
#undef CONFIG_NEVER_ASSERT_ODT_TO_CPU /* Never assert ODT to internal IOs */
diff --git a/include/configs/sbc8349.h b/include/configs/sbc8349.h
index bf7cf82..4324210 100644
--- a/include/configs/sbc8349.h
+++ b/include/configs/sbc8349.h
@@ -92,7 +92,7 @@
* DDR Setup
*/
#undef CONFIG_DDR_ECC /* only for ECC DDR module */
-#undef CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */
+#undef CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
#define CONFIG_SPD_EEPROM /* use SPD EEPROM for DDR setup*/
#define CONFIG_SYS_83XX_DDR_USES_CS0 /* WRS; Fsl board uses CS2/CS3 */
diff --git a/include/configs/vme8349.h b/include/configs/vme8349.h
index d0690fe..9e3ead9 100644
--- a/include/configs/vme8349.h
+++ b/include/configs/vme8349.h
@@ -74,7 +74,7 @@
* DDR Setup
*/
#define CONFIG_DDR_ECC /* only for ECC DDR module */
-#define CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */
+#define CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
#undef CONFIG_SPD_EEPROM /* dont use SPD EEPROM for DDR setup*/
#define CONFIG_SYS_83XX_DDR_USES_CS0 /* esd; Fsl board uses CS2/CS3 */
--
1.6.2.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [U-Boot] [PATCH 4/7] 83xx: Migrate CONFIG_DDR_ECC_CMD toCONFIG_EDAC_FSL_ECC
2009-11-09 23:37 ` [U-Boot] [PATCH 4/7] 83xx: Migrate CONFIG_DDR_ECC_CMD to CONFIG_EDAC_FSL_ECC Peter Tyser
@ 2009-11-10 0:51 ` Liu Dave-R63238
2009-11-10 1:09 ` Peter Tyser
0 siblings, 1 reply; 24+ messages in thread
From: Liu Dave-R63238 @ 2009-11-10 0:51 UTC (permalink / raw)
To: u-boot
83xx ECC test code is really perfect, but it is regretful that it can
not reused to 85xx/86xx right now.
I'm not sure which approach is better between Peter's and this.
Because I still have not read carefully Peter's code.
> Update 83xx boards to use the same ECC driver that the 85xx and 86xx
> boards currently use. The common 83xx/85xx/86xx ECC driver has
> fewer options, but better error reporting.
>
> Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
> ---
> cpu/mpc83xx/Makefile | 1 -
> cpu/mpc83xx/ecc.c | 390
> -----------------------------------------
> include/configs/MPC8349EMDS.h | 2 +-
> include/configs/MPC8360EMDS.h | 2 +-
> include/configs/MPC8360ERDK.h | 2 +-
> include/configs/MPC837XEMDS.h | 2 +-
> include/configs/MPC837XERDB.h | 2 +-
> include/configs/sbc8349.h | 2 +-
> include/configs/vme8349.h | 2 +-
> 9 files changed, 7 insertions(+), 398 deletions(-)
> delete mode 100644 cpu/mpc83xx/ecc.c
>
> diff --git a/cpu/mpc83xx/Makefile b/cpu/mpc83xx/Makefile
> index 15e2c18..8fda557 100644
> --- a/cpu/mpc83xx/Makefile
> +++ b/cpu/mpc83xx/Makefile
> @@ -35,7 +35,6 @@ COBJS-y += cpu_init.o
> COBJS-y += speed.o
> COBJS-y += interrupts.o
> COBJS-y += spd_sdram.o
> -COBJS-y += ecc.o
> COBJS-$(CONFIG_QE) += qe_io.o
> COBJS-$(CONFIG_FSL_SERDES) += serdes.o
> COBJS-$(CONFIG_PCI) += pci.o
> diff --git a/cpu/mpc83xx/ecc.c b/cpu/mpc83xx/ecc.c
> deleted file mode 100644
> index f3942b4..0000000
> --- a/cpu/mpc83xx/ecc.c
> +++ /dev/null
> @@ -1,390 +0,0 @@
> -/*
> - * Copyright (C) 2007 Freescale Semiconductor, Inc.
> - *
> - * Dave Liu <daveliu@freescale.com>
> - * based on the contribution of Marian Balakowicz <m8@semihalf.com>
> - *
> - * See file CREDITS for list of people who contributed to this
> - * project.
> - *
> - * This program is free software; you can redistribute it and/or
> - * modify it under the terms of the GNU General Public License as
> - * published by the Free Software Foundation; either version 2 of
> - * the License, or (at your option) any later version.
> - */
> -
> -#include <common.h>
> -#include <mpc83xx.h>
> -#include <command.h>
> -
> -#if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD)
> -void ecc_print_status(void)
> -{
> - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
> - volatile ddr83xx_t *ddr = &immap->ddr;
> -
> - printf("\nECC mode: %s\n\n",
> - (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF");
> -
> - /* Interrupts */
> - printf("Memory Error Interrupt Enable:\n");
> - printf(" Multiple-Bit Error Interrupt Enable: %d\n",
> - (ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0);
> - printf(" Single-Bit Error Interrupt Enable: %d\n",
> - (ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0);
> - printf(" Memory Select Error Interrupt Enable: %d\n\n",
> - (ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0);
> -
> - /* Error disable */
> - printf("Memory Error Disable:\n");
> - printf(" Multiple-Bit Error Disable: %d\n",
> - (ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0);
> - printf(" Sinle-Bit Error Disable: %d\n",
> - (ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0);
> - printf(" Memory Select Error Disable: %d\n\n",
> - (ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0);
> -
> - /* Error injection */
> - printf("Memory Data Path Error Injection Mask High/Low:
> %08x %08x\n",
> - ddr->data_err_inject_hi, ddr->data_err_inject_lo);
> -
> - printf("Memory Data Path Error Injection Mask ECC:\n");
> - printf(" ECC Mirror Byte: %d\n",
> - (ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0);
> - printf(" ECC Injection Enable: %d\n",
> - (ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0);
> - printf(" ECC Error Injection Mask: 0x%02x\n\n",
> - ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM);
> -
> - /* SBE counter/threshold */
> - printf("Memory Single-Bit Error Management (0..255):\n");
> - printf(" Single-Bit Error Threshold: %d\n",
> - (ddr->err_sbe & ECC_ERROR_MAN_SBET) >>
> ECC_ERROR_MAN_SBET_SHIFT);
> - printf(" Single-Bit Error Counter: %d\n\n",
> - (ddr->err_sbe & ECC_ERROR_MAN_SBEC) >>
> ECC_ERROR_MAN_SBEC_SHIFT);
> -
> - /* Error detect */
> - printf("Memory Error Detect:\n");
> - printf(" Multiple Memory Errors: %d\n",
> - (ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0);
> - printf(" Multiple-Bit Error: %d\n",
> - (ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0);
> - printf(" Single-Bit Error: %d\n",
> - (ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0);
> - printf(" Memory Select Error: %d\n\n",
> - (ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0);
> -
> - /* Capture data */
> - printf("Memory Error Address Capture: 0x%08x\n",
> ddr->capture_address);
> - printf("Memory Data Path Read Capture High/Low: %08x %08x\n",
> - ddr->capture_data_hi, ddr->capture_data_lo);
> - printf("Memory Data Path Read Capture ECC: 0x%02x\n\n",
> - ddr->capture_ecc & CAPTURE_ECC_ECE);
> -
> - printf("Memory Error Attributes Capture:\n");
> - printf(" Data Beat Number: %d\n",
> - (ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >>
> - ECC_CAPT_ATTR_BNUM_SHIFT);
> - printf(" Transaction Size: %d\n",
> - (ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >>
> - ECC_CAPT_ATTR_TSIZ_SHIFT);
> - printf(" Transaction Source: %d\n",
> - (ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >>
> - ECC_CAPT_ATTR_TSRC_SHIFT);
> - printf(" Transaction Type: %d\n",
> - (ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >>
> - ECC_CAPT_ATTR_TTYP_SHIFT);
> - printf(" Error Information Valid: %d\n\n",
> - ddr->capture_attributes & ECC_CAPT_ATTR_VLD);
> -}
> -
> -int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
> -{
> - volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
> - volatile ddr83xx_t *ddr = &immap->ddr;
> - volatile u32 val;
> - u64 *addr;
> - u32 count;
> - register u64 *i;
> - u32 ret[2];
> - u32 pattern[2];
> - u32 writeback[2];
> -
> - /* The pattern is written into memory to generate error */
> - pattern[0] = 0xfedcba98UL;
> - pattern[1] = 0x76543210UL;
> -
> - /* After injecting error, re-initialize the memory with
> the value */
> - writeback[0] = 0x01234567UL;
> - writeback[1] = 0x89abcdefUL;
> -
> - if (argc > 4) {
> - cmd_usage(cmdtp);
> - return 1;
> - }
> -
> - if (argc == 2) {
> - if (strcmp(argv[1], "status") == 0) {
> - ecc_print_status();
> - return 0;
> - } else if (strcmp(argv[1], "captureclear") == 0) {
> - ddr->capture_address = 0;
> - ddr->capture_data_hi = 0;
> - ddr->capture_data_lo = 0;
> - ddr->capture_ecc = 0;
> - ddr->capture_attributes = 0;
> - return 0;
> - }
> - }
> - if (argc == 3) {
> - if (strcmp(argv[1], "sbecnt") == 0) {
> - val = simple_strtoul(argv[2], NULL, 10);
> - if (val > 255) {
> - printf("Incorrect Counter value, "
> - "should be 0..255\n");
> - return 1;
> - }
> -
> - val = (val << ECC_ERROR_MAN_SBEC_SHIFT);
> - val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET);
> -
> - ddr->err_sbe = val;
> - return 0;
> - } else if (strcmp(argv[1], "sbethr") == 0) {
> - val = simple_strtoul(argv[2], NULL, 10);
> - if (val > 255) {
> - printf("Incorrect Counter value, "
> - "should be 0..255\n");
> - return 1;
> - }
> -
> - val = (val << ECC_ERROR_MAN_SBET_SHIFT);
> - val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC);
> -
> - ddr->err_sbe = val;
> - return 0;
> - } else if (strcmp(argv[1], "errdisable") == 0) {
> - val = ddr->err_disable;
> -
> - if (strcmp(argv[2], "+sbe") == 0) {
> - val |= ECC_ERROR_DISABLE_SBED;
> - } else if (strcmp(argv[2], "+mbe") == 0) {
> - val |= ECC_ERROR_DISABLE_MBED;
> - } else if (strcmp(argv[2], "+mse") == 0) {
> - val |= ECC_ERROR_DISABLE_MSED;
> - } else if (strcmp(argv[2], "+all") == 0) {
> - val |= (ECC_ERROR_DISABLE_SBED |
> - ECC_ERROR_DISABLE_MBED |
> - ECC_ERROR_DISABLE_MSED);
> - } else if (strcmp(argv[2], "-sbe") == 0) {
> - val &= ~ECC_ERROR_DISABLE_SBED;
> - } else if (strcmp(argv[2], "-mbe") == 0) {
> - val &= ~ECC_ERROR_DISABLE_MBED;
> - } else if (strcmp(argv[2], "-mse") == 0) {
> - val &= ~ECC_ERROR_DISABLE_MSED;
> - } else if (strcmp(argv[2], "-all") == 0) {
> - val &= ~(ECC_ERROR_DISABLE_SBED |
> - ECC_ERROR_DISABLE_MBED |
> - ECC_ERROR_DISABLE_MSED);
> - } else {
> - printf("Incorrect err_disable field\n");
> - return 1;
> - }
> -
> - ddr->err_disable = val;
> - __asm__ __volatile__("sync");
> - __asm__ __volatile__("isync");
> - return 0;
> - } else if (strcmp(argv[1], "errdetectclr") == 0) {
> - val = ddr->err_detect;
> -
> - if (strcmp(argv[2], "mme") == 0) {
> - val |= ECC_ERROR_DETECT_MME;
> - } else if (strcmp(argv[2], "sbe") == 0) {
> - val |= ECC_ERROR_DETECT_SBE;
> - } else if (strcmp(argv[2], "mbe") == 0) {
> - val |= ECC_ERROR_DETECT_MBE;
> - } else if (strcmp(argv[2], "mse") == 0) {
> - val |= ECC_ERROR_DETECT_MSE;
> - } else if (strcmp(argv[2], "all") == 0) {
> - val |= (ECC_ERROR_DETECT_MME |
> - ECC_ERROR_DETECT_MBE |
> - ECC_ERROR_DETECT_SBE |
> - ECC_ERROR_DETECT_MSE);
> - } else {
> - printf("Incorrect err_detect field\n");
> - return 1;
> - }
> -
> - ddr->err_detect = val;
> - return 0;
> - } else if (strcmp(argv[1], "injectdatahi") == 0) {
> - val = simple_strtoul(argv[2], NULL, 16);
> -
> - ddr->data_err_inject_hi = val;
> - return 0;
> - } else if (strcmp(argv[1], "injectdatalo") == 0) {
> - val = simple_strtoul(argv[2], NULL, 16);
> -
> - ddr->data_err_inject_lo = val;
> - return 0;
> - } else if (strcmp(argv[1], "injectecc") == 0) {
> - val = simple_strtoul(argv[2], NULL, 16);
> - if (val > 0xff) {
> - printf("Incorrect ECC inject mask, "
> - "should be 0x00..0xff\n");
> - return 1;
> - }
> - val |= (ddr->ecc_err_inject &
> ~ECC_ERR_INJECT_EEIM);
> -
> - ddr->ecc_err_inject = val;
> - return 0;
> - } else if (strcmp(argv[1], "inject") == 0) {
> - val = ddr->ecc_err_inject;
> -
> - if (strcmp(argv[2], "en") == 0)
> - val |= ECC_ERR_INJECT_EIEN;
> - else if (strcmp(argv[2], "dis") == 0)
> - val &= ~ECC_ERR_INJECT_EIEN;
> - else
> - printf("Incorrect command\n");
> -
> - ddr->ecc_err_inject = val;
> - __asm__ __volatile__("sync");
> - __asm__ __volatile__("isync");
> - return 0;
> - } else if (strcmp(argv[1], "mirror") == 0) {
> - val = ddr->ecc_err_inject;
> -
> - if (strcmp(argv[2], "en") == 0)
> - val |= ECC_ERR_INJECT_EMB;
> - else if (strcmp(argv[2], "dis") == 0)
> - val &= ~ECC_ERR_INJECT_EMB;
> - else
> - printf("Incorrect command\n");
> -
> - ddr->ecc_err_inject = val;
> - return 0;
> - }
> - }
> - if (argc == 4) {
> - if (strcmp(argv[1], "testdw") == 0) {
> - addr = (u64 *) simple_strtoul(argv[2],
> NULL, 16);
> - count = simple_strtoul(argv[3], NULL, 16);
> -
> - if ((u32) addr % 8) {
> - printf("Address not alligned on "
> - "double word boundary\n");
> - return 1;
> - }
> - disable_interrupts();
> -
> - for (i = addr; i < addr + count; i++) {
> -
> - /* enable injects */
> - ddr->ecc_err_inject |=
> ECC_ERR_INJECT_EIEN;
> - __asm__ __volatile__("sync");
> - __asm__ __volatile__("isync");
> -
> - /* write memory location
> injecting errors */
> - ppcDWstore((u32 *) i, pattern);
> - __asm__ __volatile__("sync");
> -
> - /* disable injects */
> - ddr->ecc_err_inject &=
> ~ECC_ERR_INJECT_EIEN;
> - __asm__ __volatile__("sync");
> - __asm__ __volatile__("isync");
> -
> - /* read data, this generates
> ECC error */
> - ppcDWload((u32 *) i, ret);
> - __asm__ __volatile__("sync");
> -
> - /* re-initialize memory, double
> word write the location again,
> - * generates new ECC code this time */
> - ppcDWstore((u32 *) i, writeback);
> - __asm__ __volatile__("sync");
> - }
> - enable_interrupts();
> - return 0;
> - }
> - if (strcmp(argv[1], "testword") == 0) {
> - addr = (u64 *) simple_strtoul(argv[2],
> NULL, 16);
> - count = simple_strtoul(argv[3], NULL, 16);
> -
> - if ((u32) addr % 8) {
> - printf("Address not alligned on "
> - "double word boundary\n");
> - return 1;
> - }
> - disable_interrupts();
> -
> - for (i = addr; i < addr + count; i++) {
> -
> - /* enable injects */
> - ddr->ecc_err_inject |=
> ECC_ERR_INJECT_EIEN;
> - __asm__ __volatile__("sync");
> - __asm__ __volatile__("isync");
> -
> - /* write memory location
> injecting errors */
> - *(u32 *) i = 0xfedcba98UL;
> - __asm__ __volatile__("sync");
> -
> - /* sub double word write,
> - * bus will read-modify-write,
> - * generates ECC error */
> - *((u32 *) i + 1) = 0x76543210UL;
> - __asm__ __volatile__("sync");
> -
> - /* disable injects */
> - ddr->ecc_err_inject &=
> ~ECC_ERR_INJECT_EIEN;
> - __asm__ __volatile__("sync");
> - __asm__ __volatile__("isync");
> -
> - /* re-initialize memory,
> - * double word write the location again,
> - * generates new ECC code this time */
> - ppcDWstore((u32 *) i, writeback);
> - __asm__ __volatile__("sync");
> - }
> - enable_interrupts();
> - return 0;
> - }
> - }
> - cmd_usage(cmdtp);
> - return 1;
> -}
> -
> -U_BOOT_CMD(ecc, 4, 0, do_ecc,
> - "support for DDR ECC features",
> - "status - print out status info\n"
> - "ecc captureclear - clear capture regs data\n"
> - "ecc sbecnt <val> - set Single-Bit Error counter\n"
> - "ecc sbethr <val> - set Single-Bit Threshold\n"
> - "ecc errdisable <flag> - clear/set disable Memory
> Error Disable, flag:\n"
> - " [-|+]sbe - Single-Bit Error\n"
> - " [-|+]mbe - Multiple-Bit Error\n"
> - " [-|+]mse - Memory Select Error\n"
> - " [-|+]all - all errors\n"
> - "ecc errdetectclr <flag> - clear Memory Error
> Detect, flag:\n"
> - " mme - Multiple Memory Errors\n"
> - " sbe - Single-Bit Error\n"
> - " mbe - Multiple-Bit Error\n"
> - " mse - Memory Select Error\n"
> - " all - all errors\n"
> - "ecc injectdatahi <hi> - set Memory Data Path Error
> Injection Mask High\n"
> - "ecc injectdatalo <lo> - set Memory Data Path Error
> Injection Mask Low\n"
> - "ecc injectecc <ecc> - set ECC Error Injection Mask\n"
> - "ecc inject <en|dis> - enable/disable error injection\n"
> - "ecc mirror <en|dis> - enable/disable mirror byte\n"
> - "ecc testdw <addr> <cnt> - test mem region with
> double word access:\n"
> - " - enables injects\n"
> - " - writes pattern injecting errors with double
> word access\n"
> - " - disables injects\n"
> - " - reads pattern back with double word access,
> generates error\n"
> - " - re-inits memory\n"
> - "ecc testword <addr> <cnt> - test mem region with
> word access:\n"
> - " - enables injects\n"
> - " - writes pattern injecting errors with word access\n"
> - " - writes pattern with word access, generates error\n"
> - " - disables injects\n" " - re-inits memory");
> -#endif
> diff --git a/include/configs/MPC8349EMDS.h
> b/include/configs/MPC8349EMDS.h
> index 6361c45..34fb59f 100644
> --- a/include/configs/MPC8349EMDS.h
> +++ b/include/configs/MPC8349EMDS.h
> @@ -72,7 +72,7 @@
> * DDR Setup
> */
> #define CONFIG_DDR_ECC /* support DDR
> ECC function */
> -#define CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */
> +#define CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
> #define CONFIG_SPD_EEPROM /* use SPD EEPROM for
> DDR setup*/
>
> /*
> diff --git a/include/configs/MPC8360EMDS.h
> b/include/configs/MPC8360EMDS.h
> index 8520155..fc2d456 100644
> --- a/include/configs/MPC8360EMDS.h
> +++ b/include/configs/MPC8360EMDS.h
> @@ -108,7 +108,7 @@
> #define CONFIG_SYS_83XX_DDR_USES_CS0
>
> #define CONFIG_DDR_ECC /* support DDR ECC function */
> -#define CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */
> +#define CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
>
> /*
> * DDRCDR - DDR Control Driver Register
> diff --git a/include/configs/MPC8360ERDK.h
> b/include/configs/MPC8360ERDK.h
> index 6cee78a..253c733 100644
> --- a/include/configs/MPC8360ERDK.h
> +++ b/include/configs/MPC8360ERDK.h
> @@ -90,7 +90,7 @@
> #define CONFIG_SYS_83XX_DDR_USES_CS0
>
> #define CONFIG_DDR_ECC /* support DDR ECC function */
> -#define CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */
> +#define CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
>
> /*
> * DDRCDR - DDR Control Driver Register
> diff --git a/include/configs/MPC837XEMDS.h
> b/include/configs/MPC837XEMDS.h
> index abeb6a2..45d1fa6 100644
> --- a/include/configs/MPC837XEMDS.h
> +++ b/include/configs/MPC837XEMDS.h
> @@ -129,7 +129,7 @@
> #define CONFIG_SYS_DDRCDR_VALUE 0x80080001 /* ODT
> 150ohm on SoC */
>
> #undef CONFIG_DDR_ECC /* support DDR ECC function */
> -#undef CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */
> +#undef CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
>
> #define CONFIG_SPD_EEPROM /* Use SPD EEPROM for DDR setup */
> #define CONFIG_NEVER_ASSERT_ODT_TO_CPU /* Never assert ODT
> to internal IOs */
> diff --git a/include/configs/MPC837XERDB.h
> b/include/configs/MPC837XERDB.h
> index 7ef92f7..cdde255 100644
> --- a/include/configs/MPC837XERDB.h
> +++ b/include/configs/MPC837XERDB.h
> @@ -155,7 +155,7 @@
> #define CONFIG_SYS_DDRCDR_VALUE (DDRCDR_DHC_EN |
> DDRCDR_ODT | DDRCDR_Q_DRN)
>
> #undef CONFIG_DDR_ECC /* support DDR ECC function */
> -#undef CONFIG_DDR_ECC_CMD /* Use DDR ECC user commands */
> +#undef CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
>
> #undef CONFIG_NEVER_ASSERT_ODT_TO_CPU /* Never assert
> ODT to internal IOs */
>
> diff --git a/include/configs/sbc8349.h b/include/configs/sbc8349.h
> index bf7cf82..4324210 100644
> --- a/include/configs/sbc8349.h
> +++ b/include/configs/sbc8349.h
> @@ -92,7 +92,7 @@
> * DDR Setup
> */
> #undef CONFIG_DDR_ECC /* only for ECC
> DDR module */
> -#undef CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */
> +#undef CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
> #define CONFIG_SPD_EEPROM /* use SPD EEPROM for
> DDR setup*/
> #define CONFIG_SYS_83XX_DDR_USES_CS0 /* WRS; Fsl
> board uses CS2/CS3 */
>
> diff --git a/include/configs/vme8349.h b/include/configs/vme8349.h
> index d0690fe..9e3ead9 100644
> --- a/include/configs/vme8349.h
> +++ b/include/configs/vme8349.h
> @@ -74,7 +74,7 @@
> * DDR Setup
> */
> #define CONFIG_DDR_ECC /* only for ECC
> DDR module */
> -#define CONFIG_DDR_ECC_CMD /* use DDR ECC user commands */
> +#define CONFIG_EDAC_FSL_ECC /* use DDR ECC user commands */
> #undef CONFIG_SPD_EEPROM /* dont use SPD EEPROM
> for DDR setup*/
> #define CONFIG_SYS_83XX_DDR_USES_CS0 /* esd; Fsl board uses
> CS2/CS3 */
>
> --
> 1.6.2.1
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
>
^ permalink raw reply [flat|nested] 24+ messages in thread* [U-Boot] [PATCH 4/7] 83xx: Migrate CONFIG_DDR_ECC_CMD toCONFIG_EDAC_FSL_ECC
2009-11-10 0:51 ` [U-Boot] [PATCH 4/7] 83xx: Migrate CONFIG_DDR_ECC_CMD toCONFIG_EDAC_FSL_ECC Liu Dave-R63238
@ 2009-11-10 1:09 ` Peter Tyser
0 siblings, 0 replies; 24+ messages in thread
From: Peter Tyser @ 2009-11-10 1:09 UTC (permalink / raw)
To: u-boot
Please stop top-posting.
On Tue, 2009-11-10 at 08:51 +0800, Liu Dave-R63238 wrote:
> 83xx ECC test code is really perfect, but it is regretful that it can
> not reused to 85xx/86xx right now.
> I'm not sure which approach is better between Peter's and this.
> Because I still have not read carefully Peter's code.
<snip>
The 83xx ECC test code may have been perfect for your needs, but it was
not perfect for mine:) Or most people I would think. As I mentioned
before, I put an emphasis on the error reporting. Wolfgang and I
discussed exactly this in v1 of the patch:
http://www.mail-archive.com/u-boot at lists.denx.de/msg24216.html
<quote>
> 83xx, 85xx, and 86xx could all share an implementation I believe. I
> didn't integrate the 83xx in this patch because it seemed to have a
> different "goal" than the patch I submitted. The 83xx implementation
> supported a high degree of tweaking registers which I personally find
> unnecessary for general use. I think that if someone wants that level
> of control, they could just modify the registers directly since they
> have to have the 83xx user's manual handy anyway.
Agreed.
> The implementation I submitted has limited, common features and much
> better error reporting. The error reporting is the feature that would
> be used 98% of the time, not the tweaking of registers. I'd be happy to
> include the 83xx implementation in this patch, but I'd vote to strip out
> most of the current 83xx features - ie basically remove the 83xx ecc
> code and replace it with the 85/86xx implementation I submitted. Would
> 83xx people be OK with this? Or have any suggestions on what the
> combined implementation should look like?
I have yet to see a user who actually uses the existing code on 83xx,
so as far as I am concerned I'll be fine with the common, simpler
code.
</quote>
Best,
Peter
^ permalink raw reply [flat|nested] 24+ messages in thread
* [U-Boot] [PATCH 5/7] Add check for ECC errors during SDRAM POST and mtest
2009-11-09 23:37 [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update Peter Tyser
` (3 preceding siblings ...)
2009-11-09 23:37 ` [U-Boot] [PATCH 4/7] 83xx: Migrate CONFIG_DDR_ECC_CMD to CONFIG_EDAC_FSL_ECC Peter Tyser
@ 2009-11-09 23:37 ` Peter Tyser
2009-11-09 23:37 ` [U-Boot] [PATCH 6/7] xes: Add 8xxx post support Peter Tyser
` (2 subsequent siblings)
7 siblings, 0 replies; 24+ messages in thread
From: Peter Tyser @ 2009-11-09 23:37 UTC (permalink / raw)
To: u-boot
Add a CONFIG_CHECK_ECC_ERRORS define which causes the SDRAM POST and
mtest command to check for ECC errors during execution.
The 83xx, 85xx, and 86xx architectures currently support enabling
CONFIG_CHECK_ECC_ERRORS. Other architectures/boards can use it if they
implement an ecc_count() and ecc_info() function.
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
---
common/cmd_mem.c | 10 ++++++++++
include/common.h | 6 ++++++
post/drivers/memory.c | 5 +++++
3 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index a34b342..efedf79 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -691,6 +691,11 @@ int do_mem_mtest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
__FUNCTION__, __LINE__, start, end);
for (;;) {
+#ifdef CONFIG_CHECK_ECC_ERRORS
+ if (ecc_count())
+ ecc_info();
+#endif
+
if (ctrlc()) {
putc ('\n');
return 1;
@@ -917,6 +922,11 @@ int do_mem_mtest (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
#else /* The original, quickie test */
incr = 1;
for (;;) {
+#ifdef CONFIG_CHECK_ECC_ERRORS
+ if (ecc_count())
+ ecc_info();
+#endif
+
if (ctrlc()) {
putc ('\n');
return 1;
diff --git a/include/common.h b/include/common.h
index 7df9afa..e606a74 100644
--- a/include/common.h
+++ b/include/common.h
@@ -310,6 +310,12 @@ void api_init (void);
/* common/memsize.c */
long get_ram_size (volatile long *, long);
+/* driver/edac/ */
+#ifdef CONFIG_CHECK_ECC_ERRORS
+void ecc_info(void);
+int ecc_count(void);
+#endif
+
/* $(BOARD)/$(BOARD).c */
void reset_phy (void);
void fdc_hw_init (void);
diff --git a/post/drivers/memory.c b/post/drivers/memory.c
index 0062360..b8bbac5 100644
--- a/post/drivers/memory.c
+++ b/post/drivers/memory.c
@@ -477,6 +477,11 @@ int memory_post_test (int flags)
}
}
+#ifdef CONFIG_CHECK_ECC_ERRORS
+ if (ecc_count())
+ printf("WARNING: %d ECC errors detected!!\n", ecc_count());
+#endif
+
return ret;
}
--
1.6.2.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [U-Boot] [PATCH 6/7] xes: Add 8xxx post support
2009-11-09 23:37 [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update Peter Tyser
` (4 preceding siblings ...)
2009-11-09 23:37 ` [U-Boot] [PATCH 5/7] Add check for ECC errors during SDRAM POST and mtest Peter Tyser
@ 2009-11-09 23:37 ` Peter Tyser
2009-11-09 23:37 ` [U-Boot] [PATCH 7/7] xes: Enable memory POST and ECC error reporting Peter Tyser
2009-12-16 15:55 ` [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update Peter Tyser
7 siblings, 0 replies; 24+ messages in thread
From: Peter Tyser @ 2009-11-09 23:37 UTC (permalink / raw)
To: u-boot
Note that SPRG4 is used to store U-Boot's post 'word'.
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
---
board/xes/common/Makefile | 1 +
board/xes/common/fsl_8xxx_post.c | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+), 0 deletions(-)
create mode 100644 board/xes/common/fsl_8xxx_post.c
diff --git a/board/xes/common/Makefile b/board/xes/common/Makefile
index d022831..b6297ed 100644
--- a/board/xes/common/Makefile
+++ b/board/xes/common/Makefile
@@ -33,6 +33,7 @@ COBJS-$(CONFIG_FSL_PCI_INIT) += fsl_8xxx_pci.o
COBJS-$(CONFIG_MPC8572) += fsl_8xxx_clk.o
COBJS-$(CONFIG_MPC86xx) += fsl_8xxx_clk.o
COBJS-$(CONFIG_FSL_DDR2) += fsl_8xxx_ddr.o
+COBJS-$(CONFIG_HAS_POST) += fsl_8xxx_post.o
COBJS-$(CONFIG_NAND_ACTL) += actl_nand.o
SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
diff --git a/board/xes/common/fsl_8xxx_post.c b/board/xes/common/fsl_8xxx_post.c
new file mode 100644
index 0000000..179f970
--- /dev/null
+++ b/board/xes/common/fsl_8xxx_post.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 Extreme Engineering Solutions, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/processor.h>
+
+int post_hotkeys_pressed(void) {
+ return 0;
+}
+
+void post_word_store(ulong a) {
+ mtspr(SPRG4, a);
+}
+
+ulong post_word_load(void) {
+ return mfspr(SPRG4);
+}
--
1.6.2.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [U-Boot] [PATCH 7/7] xes: Enable memory POST and ECC error reporting
2009-11-09 23:37 [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update Peter Tyser
` (5 preceding siblings ...)
2009-11-09 23:37 ` [U-Boot] [PATCH 6/7] xes: Add 8xxx post support Peter Tyser
@ 2009-11-09 23:37 ` Peter Tyser
2009-12-16 15:55 ` [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update Peter Tyser
7 siblings, 0 replies; 24+ messages in thread
From: Peter Tyser @ 2009-11-09 23:37 UTC (permalink / raw)
To: u-boot
Signed-off-by: Peter Tyser <ptyser@xes-inc.com>
---
include/configs/XPEDITE5170.h | 3 +++
include/configs/XPEDITE5200.h | 3 +++
include/configs/XPEDITE5370.h | 3 +++
3 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/include/configs/XPEDITE5170.h b/include/configs/XPEDITE5170.h
index 1a810e4..07a61bb 100644
--- a/include/configs/XPEDITE5170.h
+++ b/include/configs/XPEDITE5170.h
@@ -106,6 +106,9 @@ extern unsigned long get_board_sys_clk(unsigned long dummy);
#define CONFIG_SYS_ALT_MEMTEST
#define CONFIG_SYS_MEMTEST_START 0x10000000
#define CONFIG_SYS_MEMTEST_END 0x20000000
+#define CONFIG_POST (CONFIG_SYS_POST_MEMORY)
+#define CONFIG_CHECK_ECC_ERRORS /* Check ECC count during POST/mtest */
+#define CONFIG_EDAC_FSL_ECC /* Enable ECC checking/command */
/*
* Memory map
diff --git a/include/configs/XPEDITE5200.h b/include/configs/XPEDITE5200.h
index 3f73780..ff780ab 100644
--- a/include/configs/XPEDITE5200.h
+++ b/include/configs/XPEDITE5200.h
@@ -89,6 +89,9 @@
#define CONFIG_SYS_ALT_MEMTEST
#define CONFIG_SYS_MEMTEST_START 0x10000000
#define CONFIG_SYS_MEMTEST_END 0x20000000
+#define CONFIG_POST (CONFIG_SYS_POST_MEMORY)
+#define CONFIG_CHECK_ECC_ERRORS /* Check ECC count during POST/mtest */
+#define CONFIG_EDAC_FSL_ECC /* Enable ECC checking/command */
/*
* Memory map
diff --git a/include/configs/XPEDITE5370.h b/include/configs/XPEDITE5370.h
index 26b798b..0f80ed3 100644
--- a/include/configs/XPEDITE5370.h
+++ b/include/configs/XPEDITE5370.h
@@ -100,6 +100,9 @@ extern unsigned long get_board_ddr_clk(unsigned long dummy);
#define CONFIG_SYS_ALT_MEMTEST
#define CONFIG_SYS_MEMTEST_START 0x10000000
#define CONFIG_SYS_MEMTEST_END 0x20000000
+#define CONFIG_POST (CONFIG_SYS_POST_MEMORY)
+#define CONFIG_CHECK_ECC_ERRORS /* Check ECC count during POST/mtest */
+#define CONFIG_EDAC_FSL_ECC /* Enable ECC checking/command */
/*
* Memory map
--
1.6.2.1
^ permalink raw reply related [flat|nested] 24+ messages in thread* [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update
2009-11-09 23:37 [U-Boot] [PATCH v2 0/7] 83xx/85xx/86xx ECC update Peter Tyser
` (6 preceding siblings ...)
2009-11-09 23:37 ` [U-Boot] [PATCH 7/7] xes: Enable memory POST and ECC error reporting Peter Tyser
@ 2009-12-16 15:55 ` Peter Tyser
7 siblings, 0 replies; 24+ messages in thread
From: Peter Tyser @ 2009-12-16 15:55 UTC (permalink / raw)
To: u-boot
On Mon, 2009-11-09 at 17:37 -0600, Peter Tyser wrote:
> This patch series is similar to the "8xxx: Add 'ecc' command" recently
> submitted but has the following changes:
> - Supports 83xx/85xx/86xx, previously 83xx wasn't supported
> - Removes the old 83xx ecc command and replaces it with this new
> implementation
> - Places the ecc code in a new drivers/edac directory instead of
> in cpu/8xxx
> - The ecc command is enabled via CONFIG_EDAC_FSL_ECC instead of
> CONFIG_CMD_ECC
>
> I compile tested on 83xx, but don't have any 83xx boards to test
> on, so it'd be much appreciated if someone else could give it a shot.
> If people don't want to actually ground signals on their boards,
> they can inject an error then modify memory or perform a mtest to
> simulate ecc errors.
Ping...
^ permalink raw reply [flat|nested] 24+ messages in thread