diff options
Diffstat (limited to 'arch/powerpc/cpu/ppc4xx/cmd_ecctest.c')
-rw-r--r-- | arch/powerpc/cpu/ppc4xx/cmd_ecctest.c | 262 |
1 files changed, 0 insertions, 262 deletions
diff --git a/arch/powerpc/cpu/ppc4xx/cmd_ecctest.c b/arch/powerpc/cpu/ppc4xx/cmd_ecctest.c deleted file mode 100644 index 958ba6c94d..0000000000 --- a/arch/powerpc/cpu/ppc4xx/cmd_ecctest.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * (C) Copyright 2010 - * Stefan Roese, DENX Software Engineering, sr@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/ppc4xx.h> -#include <asm/processor.h> -#include <asm/io.h> -#include <asm/cache.h> - -#if defined(CONFIG_SDRAM_PPC4xx_IBM_DDR) || \ - defined(CONFIG_SDRAM_PPC4xx_IBM_DDR2) -#if defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) - -#if defined(CONFIG_405EX) -/* - * Currently only 405EX uses 16bit data bus width as an alternative - * option to 32bit data width (SDRAM0_MCOPT1_WDTH) - */ -#define SDRAM_DATA_ALT_WIDTH 2 -#else -#define SDRAM_DATA_ALT_WIDTH 8 -#endif - -#if defined(CONFIG_SYS_OCM_BASE) -#define CONFIG_FUNC_ISRAM_ADDR CONFIG_SYS_OCM_BASE -#endif - -#if defined(CONFIG_SYS_ISRAM_BASE) -#define CONFIG_FUNC_ISRAM_ADDR CONFIG_SYS_ISRAM_BASE -#endif - -#if !defined(CONFIG_FUNC_ISRAM_ADDR) -#error "No internal SRAM/OCM provided!" -#endif - -#define force_inline inline __attribute__ ((always_inline)) - -static inline void machine_check_disable(void) -{ - mtmsr(mfmsr() & ~MSR_ME); -} - -static inline void machine_check_enable(void) -{ - mtmsr(mfmsr() | MSR_ME); -} - -/* - * These helper functions need to be inlined, since they - * are called from the functions running from internal SRAM. - * SDRAM operation is forbidden at that time, so calling - * functions in SDRAM has to be avoided. - */ -static force_inline void wait_ddr_idle(void) -{ - u32 val; - - do { - mfsdram(SDRAM_MCSTAT, val); - } while ((val & SDRAM_MCSTAT_IDLE_MASK) == SDRAM_MCSTAT_IDLE_NOT); -} - -static force_inline void recalibrate_ddr(void) -{ - u32 val; - - /* - * Rewrite RQDC & RFDC to calibrate again. If this is not - * done, the SDRAM controller is working correctly after - * changing the MCOPT1_MCHK bits. - */ - mfsdram(SDRAM_RQDC, val); - mtsdram(SDRAM_RQDC, val); - mfsdram(SDRAM_RFDC, val); - mtsdram(SDRAM_RFDC, val); -} - -static force_inline void set_mcopt1_mchk(u32 bits) -{ - u32 val; - - wait_ddr_idle(); - mfsdram(SDRAM_MCOPT1, val); - mtsdram(SDRAM_MCOPT1, (val & ~SDRAM_MCOPT1_MCHK_MASK) | bits); - recalibrate_ddr(); -} - -/* - * The next 2 functions are copied to internal SRAM/OCM and run - * there. No function calls allowed here. No SDRAM acitivity should - * be done here. - */ -static void inject_ecc_error(void *ptr, int par) -{ - /* - * Taken from PPC460EX/EXr/GT users manual (Rev 1.21) - * 22.2.17.13 ECC Diagnostics - * - * Items 1 ... 5 are already done by now, running from RAM - * with ECC enabled - */ - - out_be32(ptr, 0x00000000); - in_be32(ptr); - - /* 6. Set memory controller to no error checking */ - set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_NON); - - /* 7. Modify one or two bits for error simulation */ - if (par == 1) - out_be32(ptr, in_be32(ptr) ^ 0x00000001); - else - out_be32(ptr, in_be32(ptr) ^ 0x00000003); - - /* 8. Wait for SDRAM idle */ - in_be32(ptr); - set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_CHK_REP); - - /* Wait for SDRAM idle */ - wait_ddr_idle(); - - /* Continue with 9. in calling function... */ -} - -static void rewrite_ecc_parity(void *ptr, int par) -{ - u32 current_address = (u32)ptr; - u32 end_address; - u32 address_increment; - u32 mcopt1; - - /* - * Fill ECC parity byte again. Otherwise further accesses to - * the failure address will result in exceptions. - */ - - /* Wait for SDRAM idle */ - in_be32(0x00000000); - set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_GEN); - - /* ECC bit set method for non-cached memory */ - mfsdram(SDRAM_MCOPT1, mcopt1); - if ((mcopt1 & SDRAM_MCOPT1_DMWD_MASK) == SDRAM_MCOPT1_DMWD_32) - address_increment = 4; - else - address_increment = SDRAM_DATA_ALT_WIDTH; - end_address = current_address + CONFIG_SYS_CACHELINE_SIZE; - - while (current_address < end_address) { - *((unsigned long *)current_address) = 0; - current_address += address_increment; - } - - set_mcopt1_mchk(SDRAM_MCOPT1_MCHK_CHK_REP); - - /* Wait for SDRAM idle */ - wait_ddr_idle(); -} - -static int do_ecctest(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - u32 old_val; - u32 val; - u32 *ptr; - void (*sram_func)(u32 *, int); - int error; - - if (argc < 3) { - return cmd_usage(cmdtp); - } - - ptr = (u32 *)simple_strtoul(argv[1], NULL, 16); - error = simple_strtoul(argv[2], NULL, 16); - if ((error < 1) || (error > 2)) { - return cmd_usage(cmdtp); - } - - printf("Using address %p for %d bit ECC error injection\n", - ptr, error); - - /* - * Save value to restore it later on - */ - old_val = in_be32(ptr); - - /* - * Copy ECC injection function into internal SRAM/OCM - */ - sram_func = (void *)CONFIG_FUNC_ISRAM_ADDR; - memcpy((void *)CONFIG_FUNC_ISRAM_ADDR, inject_ecc_error, 0x10000); - - /* - * Disable interrupts and exceptions before calling this - * function in internal SRAM/OCM - */ - disable_interrupts(); - machine_check_disable(); - eieio(); - - /* - * Jump to ECC simulation function in internal SRAM/OCM - */ - (*sram_func)(ptr, error); - - /* 10. Read the corresponding address */ - val = in_be32(ptr); - - /* - * Read and print ECC status register/info: - * The faulting address is only known upon uncorrectable ECC - * errors. - */ - mfsdram(SDRAM_ECCES, val); - if (val & SDRAM_ECCES_CE) - printf("ECC: Correctable error\n"); - if (val & SDRAM_ECCES_UE) { - printf("ECC: Uncorrectable error at 0x%02x%08x\n", - mfdcr(SDRAM_ERRADDULL), mfdcr(SDRAM_ERRADDLLL)); - } - - /* - * Clear pending interrupts/exceptions - */ - mtsdram(SDRAM_ECCES, 0xffffffff); - mtdcr(SDRAM_ERRSTATLL, 0xff000000); - set_mcsr(get_mcsr()); - - /* Now enable interrupts and exceptions again */ - eieio(); - machine_check_enable(); - enable_interrupts(); - - /* - * The ECC parity byte need to be re-written for the - * corresponding address. Otherwise future accesses to it - * will result in exceptions. - * - * Jump to ECC parity generation function - */ - memcpy((void *)CONFIG_FUNC_ISRAM_ADDR, rewrite_ecc_parity, 0x10000); - (*sram_func)(ptr, 0); - - /* - * Restore value in corresponding address - */ - out_be32(ptr, old_val); - - return 0; -} - -U_BOOT_CMD( - ecctest, 3, 0, do_ecctest, - "Test ECC by single and double error bit injection", - "address 1/2" -); - -#endif /* defined(CONFIG_DDR_ECC) || defined(CONFIG_SDRAM_ECC) */ -#endif /* defined(CONFIG_SDRAM_PPC4xx_IBM_DDR)... */ |