1*a47a12beSStefan Roese /* 2*a47a12beSStefan Roese * Copyright (C) 2007 Freescale Semiconductor, Inc. 3*a47a12beSStefan Roese * 4*a47a12beSStefan Roese * Dave Liu <daveliu@freescale.com> 5*a47a12beSStefan Roese * based on the contribution of Marian Balakowicz <m8@semihalf.com> 6*a47a12beSStefan Roese * 7*a47a12beSStefan Roese * See file CREDITS for list of people who contributed to this 8*a47a12beSStefan Roese * project. 9*a47a12beSStefan Roese * 10*a47a12beSStefan Roese * This program is free software; you can redistribute it and/or 11*a47a12beSStefan Roese * modify it under the terms of the GNU General Public License as 12*a47a12beSStefan Roese * published by the Free Software Foundation; either version 2 of 13*a47a12beSStefan Roese * the License, or (at your option) any later version. 14*a47a12beSStefan Roese */ 15*a47a12beSStefan Roese 16*a47a12beSStefan Roese #include <common.h> 17*a47a12beSStefan Roese #include <mpc83xx.h> 18*a47a12beSStefan Roese #include <command.h> 19*a47a12beSStefan Roese 20*a47a12beSStefan Roese #if defined(CONFIG_DDR_ECC) && defined(CONFIG_DDR_ECC_CMD) 21*a47a12beSStefan Roese void ecc_print_status(void) 22*a47a12beSStefan Roese { 23*a47a12beSStefan Roese volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 24*a47a12beSStefan Roese volatile ddr83xx_t *ddr = &immap->ddr; 25*a47a12beSStefan Roese 26*a47a12beSStefan Roese printf("\nECC mode: %s\n\n", 27*a47a12beSStefan Roese (ddr->sdram_cfg & SDRAM_CFG_ECC_EN) ? "ON" : "OFF"); 28*a47a12beSStefan Roese 29*a47a12beSStefan Roese /* Interrupts */ 30*a47a12beSStefan Roese printf("Memory Error Interrupt Enable:\n"); 31*a47a12beSStefan Roese printf(" Multiple-Bit Error Interrupt Enable: %d\n", 32*a47a12beSStefan Roese (ddr->err_int_en & ECC_ERR_INT_EN_MBEE) ? 1 : 0); 33*a47a12beSStefan Roese printf(" Single-Bit Error Interrupt Enable: %d\n", 34*a47a12beSStefan Roese (ddr->err_int_en & ECC_ERR_INT_EN_SBEE) ? 1 : 0); 35*a47a12beSStefan Roese printf(" Memory Select Error Interrupt Enable: %d\n\n", 36*a47a12beSStefan Roese (ddr->err_int_en & ECC_ERR_INT_EN_MSEE) ? 1 : 0); 37*a47a12beSStefan Roese 38*a47a12beSStefan Roese /* Error disable */ 39*a47a12beSStefan Roese printf("Memory Error Disable:\n"); 40*a47a12beSStefan Roese printf(" Multiple-Bit Error Disable: %d\n", 41*a47a12beSStefan Roese (ddr->err_disable & ECC_ERROR_DISABLE_MBED) ? 1 : 0); 42*a47a12beSStefan Roese printf(" Sinle-Bit Error Disable: %d\n", 43*a47a12beSStefan Roese (ddr->err_disable & ECC_ERROR_DISABLE_SBED) ? 1 : 0); 44*a47a12beSStefan Roese printf(" Memory Select Error Disable: %d\n\n", 45*a47a12beSStefan Roese (ddr->err_disable & ECC_ERROR_DISABLE_MSED) ? 1 : 0); 46*a47a12beSStefan Roese 47*a47a12beSStefan Roese /* Error injection */ 48*a47a12beSStefan Roese printf("Memory Data Path Error Injection Mask High/Low: %08x %08x\n", 49*a47a12beSStefan Roese ddr->data_err_inject_hi, ddr->data_err_inject_lo); 50*a47a12beSStefan Roese 51*a47a12beSStefan Roese printf("Memory Data Path Error Injection Mask ECC:\n"); 52*a47a12beSStefan Roese printf(" ECC Mirror Byte: %d\n", 53*a47a12beSStefan Roese (ddr->ecc_err_inject & ECC_ERR_INJECT_EMB) ? 1 : 0); 54*a47a12beSStefan Roese printf(" ECC Injection Enable: %d\n", 55*a47a12beSStefan Roese (ddr->ecc_err_inject & ECC_ERR_INJECT_EIEN) ? 1 : 0); 56*a47a12beSStefan Roese printf(" ECC Error Injection Mask: 0x%02x\n\n", 57*a47a12beSStefan Roese ddr->ecc_err_inject & ECC_ERR_INJECT_EEIM); 58*a47a12beSStefan Roese 59*a47a12beSStefan Roese /* SBE counter/threshold */ 60*a47a12beSStefan Roese printf("Memory Single-Bit Error Management (0..255):\n"); 61*a47a12beSStefan Roese printf(" Single-Bit Error Threshold: %d\n", 62*a47a12beSStefan Roese (ddr->err_sbe & ECC_ERROR_MAN_SBET) >> ECC_ERROR_MAN_SBET_SHIFT); 63*a47a12beSStefan Roese printf(" Single-Bit Error Counter: %d\n\n", 64*a47a12beSStefan Roese (ddr->err_sbe & ECC_ERROR_MAN_SBEC) >> ECC_ERROR_MAN_SBEC_SHIFT); 65*a47a12beSStefan Roese 66*a47a12beSStefan Roese /* Error detect */ 67*a47a12beSStefan Roese printf("Memory Error Detect:\n"); 68*a47a12beSStefan Roese printf(" Multiple Memory Errors: %d\n", 69*a47a12beSStefan Roese (ddr->err_detect & ECC_ERROR_DETECT_MME) ? 1 : 0); 70*a47a12beSStefan Roese printf(" Multiple-Bit Error: %d\n", 71*a47a12beSStefan Roese (ddr->err_detect & ECC_ERROR_DETECT_MBE) ? 1 : 0); 72*a47a12beSStefan Roese printf(" Single-Bit Error: %d\n", 73*a47a12beSStefan Roese (ddr->err_detect & ECC_ERROR_DETECT_SBE) ? 1 : 0); 74*a47a12beSStefan Roese printf(" Memory Select Error: %d\n\n", 75*a47a12beSStefan Roese (ddr->err_detect & ECC_ERROR_DETECT_MSE) ? 1 : 0); 76*a47a12beSStefan Roese 77*a47a12beSStefan Roese /* Capture data */ 78*a47a12beSStefan Roese printf("Memory Error Address Capture: 0x%08x\n", ddr->capture_address); 79*a47a12beSStefan Roese printf("Memory Data Path Read Capture High/Low: %08x %08x\n", 80*a47a12beSStefan Roese ddr->capture_data_hi, ddr->capture_data_lo); 81*a47a12beSStefan Roese printf("Memory Data Path Read Capture ECC: 0x%02x\n\n", 82*a47a12beSStefan Roese ddr->capture_ecc & CAPTURE_ECC_ECE); 83*a47a12beSStefan Roese 84*a47a12beSStefan Roese printf("Memory Error Attributes Capture:\n"); 85*a47a12beSStefan Roese printf(" Data Beat Number: %d\n", 86*a47a12beSStefan Roese (ddr->capture_attributes & ECC_CAPT_ATTR_BNUM) >> 87*a47a12beSStefan Roese ECC_CAPT_ATTR_BNUM_SHIFT); 88*a47a12beSStefan Roese printf(" Transaction Size: %d\n", 89*a47a12beSStefan Roese (ddr->capture_attributes & ECC_CAPT_ATTR_TSIZ) >> 90*a47a12beSStefan Roese ECC_CAPT_ATTR_TSIZ_SHIFT); 91*a47a12beSStefan Roese printf(" Transaction Source: %d\n", 92*a47a12beSStefan Roese (ddr->capture_attributes & ECC_CAPT_ATTR_TSRC) >> 93*a47a12beSStefan Roese ECC_CAPT_ATTR_TSRC_SHIFT); 94*a47a12beSStefan Roese printf(" Transaction Type: %d\n", 95*a47a12beSStefan Roese (ddr->capture_attributes & ECC_CAPT_ATTR_TTYP) >> 96*a47a12beSStefan Roese ECC_CAPT_ATTR_TTYP_SHIFT); 97*a47a12beSStefan Roese printf(" Error Information Valid: %d\n\n", 98*a47a12beSStefan Roese ddr->capture_attributes & ECC_CAPT_ATTR_VLD); 99*a47a12beSStefan Roese } 100*a47a12beSStefan Roese 101*a47a12beSStefan Roese int do_ecc(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) 102*a47a12beSStefan Roese { 103*a47a12beSStefan Roese volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR; 104*a47a12beSStefan Roese volatile ddr83xx_t *ddr = &immap->ddr; 105*a47a12beSStefan Roese volatile u32 val; 106*a47a12beSStefan Roese u64 *addr; 107*a47a12beSStefan Roese u32 count; 108*a47a12beSStefan Roese register u64 *i; 109*a47a12beSStefan Roese u32 ret[2]; 110*a47a12beSStefan Roese u32 pattern[2]; 111*a47a12beSStefan Roese u32 writeback[2]; 112*a47a12beSStefan Roese 113*a47a12beSStefan Roese /* The pattern is written into memory to generate error */ 114*a47a12beSStefan Roese pattern[0] = 0xfedcba98UL; 115*a47a12beSStefan Roese pattern[1] = 0x76543210UL; 116*a47a12beSStefan Roese 117*a47a12beSStefan Roese /* After injecting error, re-initialize the memory with the value */ 118*a47a12beSStefan Roese writeback[0] = 0x01234567UL; 119*a47a12beSStefan Roese writeback[1] = 0x89abcdefUL; 120*a47a12beSStefan Roese 121*a47a12beSStefan Roese if (argc > 4) { 122*a47a12beSStefan Roese cmd_usage(cmdtp); 123*a47a12beSStefan Roese return 1; 124*a47a12beSStefan Roese } 125*a47a12beSStefan Roese 126*a47a12beSStefan Roese if (argc == 2) { 127*a47a12beSStefan Roese if (strcmp(argv[1], "status") == 0) { 128*a47a12beSStefan Roese ecc_print_status(); 129*a47a12beSStefan Roese return 0; 130*a47a12beSStefan Roese } else if (strcmp(argv[1], "captureclear") == 0) { 131*a47a12beSStefan Roese ddr->capture_address = 0; 132*a47a12beSStefan Roese ddr->capture_data_hi = 0; 133*a47a12beSStefan Roese ddr->capture_data_lo = 0; 134*a47a12beSStefan Roese ddr->capture_ecc = 0; 135*a47a12beSStefan Roese ddr->capture_attributes = 0; 136*a47a12beSStefan Roese return 0; 137*a47a12beSStefan Roese } 138*a47a12beSStefan Roese } 139*a47a12beSStefan Roese if (argc == 3) { 140*a47a12beSStefan Roese if (strcmp(argv[1], "sbecnt") == 0) { 141*a47a12beSStefan Roese val = simple_strtoul(argv[2], NULL, 10); 142*a47a12beSStefan Roese if (val > 255) { 143*a47a12beSStefan Roese printf("Incorrect Counter value, " 144*a47a12beSStefan Roese "should be 0..255\n"); 145*a47a12beSStefan Roese return 1; 146*a47a12beSStefan Roese } 147*a47a12beSStefan Roese 148*a47a12beSStefan Roese val = (val << ECC_ERROR_MAN_SBEC_SHIFT); 149*a47a12beSStefan Roese val |= (ddr->err_sbe & ECC_ERROR_MAN_SBET); 150*a47a12beSStefan Roese 151*a47a12beSStefan Roese ddr->err_sbe = val; 152*a47a12beSStefan Roese return 0; 153*a47a12beSStefan Roese } else if (strcmp(argv[1], "sbethr") == 0) { 154*a47a12beSStefan Roese val = simple_strtoul(argv[2], NULL, 10); 155*a47a12beSStefan Roese if (val > 255) { 156*a47a12beSStefan Roese printf("Incorrect Counter value, " 157*a47a12beSStefan Roese "should be 0..255\n"); 158*a47a12beSStefan Roese return 1; 159*a47a12beSStefan Roese } 160*a47a12beSStefan Roese 161*a47a12beSStefan Roese val = (val << ECC_ERROR_MAN_SBET_SHIFT); 162*a47a12beSStefan Roese val |= (ddr->err_sbe & ECC_ERROR_MAN_SBEC); 163*a47a12beSStefan Roese 164*a47a12beSStefan Roese ddr->err_sbe = val; 165*a47a12beSStefan Roese return 0; 166*a47a12beSStefan Roese } else if (strcmp(argv[1], "errdisable") == 0) { 167*a47a12beSStefan Roese val = ddr->err_disable; 168*a47a12beSStefan Roese 169*a47a12beSStefan Roese if (strcmp(argv[2], "+sbe") == 0) { 170*a47a12beSStefan Roese val |= ECC_ERROR_DISABLE_SBED; 171*a47a12beSStefan Roese } else if (strcmp(argv[2], "+mbe") == 0) { 172*a47a12beSStefan Roese val |= ECC_ERROR_DISABLE_MBED; 173*a47a12beSStefan Roese } else if (strcmp(argv[2], "+mse") == 0) { 174*a47a12beSStefan Roese val |= ECC_ERROR_DISABLE_MSED; 175*a47a12beSStefan Roese } else if (strcmp(argv[2], "+all") == 0) { 176*a47a12beSStefan Roese val |= (ECC_ERROR_DISABLE_SBED | 177*a47a12beSStefan Roese ECC_ERROR_DISABLE_MBED | 178*a47a12beSStefan Roese ECC_ERROR_DISABLE_MSED); 179*a47a12beSStefan Roese } else if (strcmp(argv[2], "-sbe") == 0) { 180*a47a12beSStefan Roese val &= ~ECC_ERROR_DISABLE_SBED; 181*a47a12beSStefan Roese } else if (strcmp(argv[2], "-mbe") == 0) { 182*a47a12beSStefan Roese val &= ~ECC_ERROR_DISABLE_MBED; 183*a47a12beSStefan Roese } else if (strcmp(argv[2], "-mse") == 0) { 184*a47a12beSStefan Roese val &= ~ECC_ERROR_DISABLE_MSED; 185*a47a12beSStefan Roese } else if (strcmp(argv[2], "-all") == 0) { 186*a47a12beSStefan Roese val &= ~(ECC_ERROR_DISABLE_SBED | 187*a47a12beSStefan Roese ECC_ERROR_DISABLE_MBED | 188*a47a12beSStefan Roese ECC_ERROR_DISABLE_MSED); 189*a47a12beSStefan Roese } else { 190*a47a12beSStefan Roese printf("Incorrect err_disable field\n"); 191*a47a12beSStefan Roese return 1; 192*a47a12beSStefan Roese } 193*a47a12beSStefan Roese 194*a47a12beSStefan Roese ddr->err_disable = val; 195*a47a12beSStefan Roese __asm__ __volatile__("sync"); 196*a47a12beSStefan Roese __asm__ __volatile__("isync"); 197*a47a12beSStefan Roese return 0; 198*a47a12beSStefan Roese } else if (strcmp(argv[1], "errdetectclr") == 0) { 199*a47a12beSStefan Roese val = ddr->err_detect; 200*a47a12beSStefan Roese 201*a47a12beSStefan Roese if (strcmp(argv[2], "mme") == 0) { 202*a47a12beSStefan Roese val |= ECC_ERROR_DETECT_MME; 203*a47a12beSStefan Roese } else if (strcmp(argv[2], "sbe") == 0) { 204*a47a12beSStefan Roese val |= ECC_ERROR_DETECT_SBE; 205*a47a12beSStefan Roese } else if (strcmp(argv[2], "mbe") == 0) { 206*a47a12beSStefan Roese val |= ECC_ERROR_DETECT_MBE; 207*a47a12beSStefan Roese } else if (strcmp(argv[2], "mse") == 0) { 208*a47a12beSStefan Roese val |= ECC_ERROR_DETECT_MSE; 209*a47a12beSStefan Roese } else if (strcmp(argv[2], "all") == 0) { 210*a47a12beSStefan Roese val |= (ECC_ERROR_DETECT_MME | 211*a47a12beSStefan Roese ECC_ERROR_DETECT_MBE | 212*a47a12beSStefan Roese ECC_ERROR_DETECT_SBE | 213*a47a12beSStefan Roese ECC_ERROR_DETECT_MSE); 214*a47a12beSStefan Roese } else { 215*a47a12beSStefan Roese printf("Incorrect err_detect field\n"); 216*a47a12beSStefan Roese return 1; 217*a47a12beSStefan Roese } 218*a47a12beSStefan Roese 219*a47a12beSStefan Roese ddr->err_detect = val; 220*a47a12beSStefan Roese return 0; 221*a47a12beSStefan Roese } else if (strcmp(argv[1], "injectdatahi") == 0) { 222*a47a12beSStefan Roese val = simple_strtoul(argv[2], NULL, 16); 223*a47a12beSStefan Roese 224*a47a12beSStefan Roese ddr->data_err_inject_hi = val; 225*a47a12beSStefan Roese return 0; 226*a47a12beSStefan Roese } else if (strcmp(argv[1], "injectdatalo") == 0) { 227*a47a12beSStefan Roese val = simple_strtoul(argv[2], NULL, 16); 228*a47a12beSStefan Roese 229*a47a12beSStefan Roese ddr->data_err_inject_lo = val; 230*a47a12beSStefan Roese return 0; 231*a47a12beSStefan Roese } else if (strcmp(argv[1], "injectecc") == 0) { 232*a47a12beSStefan Roese val = simple_strtoul(argv[2], NULL, 16); 233*a47a12beSStefan Roese if (val > 0xff) { 234*a47a12beSStefan Roese printf("Incorrect ECC inject mask, " 235*a47a12beSStefan Roese "should be 0x00..0xff\n"); 236*a47a12beSStefan Roese return 1; 237*a47a12beSStefan Roese } 238*a47a12beSStefan Roese val |= (ddr->ecc_err_inject & ~ECC_ERR_INJECT_EEIM); 239*a47a12beSStefan Roese 240*a47a12beSStefan Roese ddr->ecc_err_inject = val; 241*a47a12beSStefan Roese return 0; 242*a47a12beSStefan Roese } else if (strcmp(argv[1], "inject") == 0) { 243*a47a12beSStefan Roese val = ddr->ecc_err_inject; 244*a47a12beSStefan Roese 245*a47a12beSStefan Roese if (strcmp(argv[2], "en") == 0) 246*a47a12beSStefan Roese val |= ECC_ERR_INJECT_EIEN; 247*a47a12beSStefan Roese else if (strcmp(argv[2], "dis") == 0) 248*a47a12beSStefan Roese val &= ~ECC_ERR_INJECT_EIEN; 249*a47a12beSStefan Roese else 250*a47a12beSStefan Roese printf("Incorrect command\n"); 251*a47a12beSStefan Roese 252*a47a12beSStefan Roese ddr->ecc_err_inject = val; 253*a47a12beSStefan Roese __asm__ __volatile__("sync"); 254*a47a12beSStefan Roese __asm__ __volatile__("isync"); 255*a47a12beSStefan Roese return 0; 256*a47a12beSStefan Roese } else if (strcmp(argv[1], "mirror") == 0) { 257*a47a12beSStefan Roese val = ddr->ecc_err_inject; 258*a47a12beSStefan Roese 259*a47a12beSStefan Roese if (strcmp(argv[2], "en") == 0) 260*a47a12beSStefan Roese val |= ECC_ERR_INJECT_EMB; 261*a47a12beSStefan Roese else if (strcmp(argv[2], "dis") == 0) 262*a47a12beSStefan Roese val &= ~ECC_ERR_INJECT_EMB; 263*a47a12beSStefan Roese else 264*a47a12beSStefan Roese printf("Incorrect command\n"); 265*a47a12beSStefan Roese 266*a47a12beSStefan Roese ddr->ecc_err_inject = val; 267*a47a12beSStefan Roese return 0; 268*a47a12beSStefan Roese } 269*a47a12beSStefan Roese } 270*a47a12beSStefan Roese if (argc == 4) { 271*a47a12beSStefan Roese if (strcmp(argv[1], "testdw") == 0) { 272*a47a12beSStefan Roese addr = (u64 *) simple_strtoul(argv[2], NULL, 16); 273*a47a12beSStefan Roese count = simple_strtoul(argv[3], NULL, 16); 274*a47a12beSStefan Roese 275*a47a12beSStefan Roese if ((u32) addr % 8) { 276*a47a12beSStefan Roese printf("Address not alligned on " 277*a47a12beSStefan Roese "double word boundary\n"); 278*a47a12beSStefan Roese return 1; 279*a47a12beSStefan Roese } 280*a47a12beSStefan Roese disable_interrupts(); 281*a47a12beSStefan Roese 282*a47a12beSStefan Roese for (i = addr; i < addr + count; i++) { 283*a47a12beSStefan Roese 284*a47a12beSStefan Roese /* enable injects */ 285*a47a12beSStefan Roese ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN; 286*a47a12beSStefan Roese __asm__ __volatile__("sync"); 287*a47a12beSStefan Roese __asm__ __volatile__("isync"); 288*a47a12beSStefan Roese 289*a47a12beSStefan Roese /* write memory location injecting errors */ 290*a47a12beSStefan Roese ppcDWstore((u32 *) i, pattern); 291*a47a12beSStefan Roese __asm__ __volatile__("sync"); 292*a47a12beSStefan Roese 293*a47a12beSStefan Roese /* disable injects */ 294*a47a12beSStefan Roese ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN; 295*a47a12beSStefan Roese __asm__ __volatile__("sync"); 296*a47a12beSStefan Roese __asm__ __volatile__("isync"); 297*a47a12beSStefan Roese 298*a47a12beSStefan Roese /* read data, this generates ECC error */ 299*a47a12beSStefan Roese ppcDWload((u32 *) i, ret); 300*a47a12beSStefan Roese __asm__ __volatile__("sync"); 301*a47a12beSStefan Roese 302*a47a12beSStefan Roese /* re-initialize memory, double word write the location again, 303*a47a12beSStefan Roese * generates new ECC code this time */ 304*a47a12beSStefan Roese ppcDWstore((u32 *) i, writeback); 305*a47a12beSStefan Roese __asm__ __volatile__("sync"); 306*a47a12beSStefan Roese } 307*a47a12beSStefan Roese enable_interrupts(); 308*a47a12beSStefan Roese return 0; 309*a47a12beSStefan Roese } 310*a47a12beSStefan Roese if (strcmp(argv[1], "testword") == 0) { 311*a47a12beSStefan Roese addr = (u64 *) simple_strtoul(argv[2], NULL, 16); 312*a47a12beSStefan Roese count = simple_strtoul(argv[3], NULL, 16); 313*a47a12beSStefan Roese 314*a47a12beSStefan Roese if ((u32) addr % 8) { 315*a47a12beSStefan Roese printf("Address not alligned on " 316*a47a12beSStefan Roese "double word boundary\n"); 317*a47a12beSStefan Roese return 1; 318*a47a12beSStefan Roese } 319*a47a12beSStefan Roese disable_interrupts(); 320*a47a12beSStefan Roese 321*a47a12beSStefan Roese for (i = addr; i < addr + count; i++) { 322*a47a12beSStefan Roese 323*a47a12beSStefan Roese /* enable injects */ 324*a47a12beSStefan Roese ddr->ecc_err_inject |= ECC_ERR_INJECT_EIEN; 325*a47a12beSStefan Roese __asm__ __volatile__("sync"); 326*a47a12beSStefan Roese __asm__ __volatile__("isync"); 327*a47a12beSStefan Roese 328*a47a12beSStefan Roese /* write memory location injecting errors */ 329*a47a12beSStefan Roese *(u32 *) i = 0xfedcba98UL; 330*a47a12beSStefan Roese __asm__ __volatile__("sync"); 331*a47a12beSStefan Roese 332*a47a12beSStefan Roese /* sub double word write, 333*a47a12beSStefan Roese * bus will read-modify-write, 334*a47a12beSStefan Roese * generates ECC error */ 335*a47a12beSStefan Roese *((u32 *) i + 1) = 0x76543210UL; 336*a47a12beSStefan Roese __asm__ __volatile__("sync"); 337*a47a12beSStefan Roese 338*a47a12beSStefan Roese /* disable injects */ 339*a47a12beSStefan Roese ddr->ecc_err_inject &= ~ECC_ERR_INJECT_EIEN; 340*a47a12beSStefan Roese __asm__ __volatile__("sync"); 341*a47a12beSStefan Roese __asm__ __volatile__("isync"); 342*a47a12beSStefan Roese 343*a47a12beSStefan Roese /* re-initialize memory, 344*a47a12beSStefan Roese * double word write the location again, 345*a47a12beSStefan Roese * generates new ECC code this time */ 346*a47a12beSStefan Roese ppcDWstore((u32 *) i, writeback); 347*a47a12beSStefan Roese __asm__ __volatile__("sync"); 348*a47a12beSStefan Roese } 349*a47a12beSStefan Roese enable_interrupts(); 350*a47a12beSStefan Roese return 0; 351*a47a12beSStefan Roese } 352*a47a12beSStefan Roese } 353*a47a12beSStefan Roese cmd_usage(cmdtp); 354*a47a12beSStefan Roese return 1; 355*a47a12beSStefan Roese } 356*a47a12beSStefan Roese 357*a47a12beSStefan Roese U_BOOT_CMD(ecc, 4, 0, do_ecc, 358*a47a12beSStefan Roese "support for DDR ECC features", 359*a47a12beSStefan Roese "status - print out status info\n" 360*a47a12beSStefan Roese "ecc captureclear - clear capture regs data\n" 361*a47a12beSStefan Roese "ecc sbecnt <val> - set Single-Bit Error counter\n" 362*a47a12beSStefan Roese "ecc sbethr <val> - set Single-Bit Threshold\n" 363*a47a12beSStefan Roese "ecc errdisable <flag> - clear/set disable Memory Error Disable, flag:\n" 364*a47a12beSStefan Roese " [-|+]sbe - Single-Bit Error\n" 365*a47a12beSStefan Roese " [-|+]mbe - Multiple-Bit Error\n" 366*a47a12beSStefan Roese " [-|+]mse - Memory Select Error\n" 367*a47a12beSStefan Roese " [-|+]all - all errors\n" 368*a47a12beSStefan Roese "ecc errdetectclr <flag> - clear Memory Error Detect, flag:\n" 369*a47a12beSStefan Roese " mme - Multiple Memory Errors\n" 370*a47a12beSStefan Roese " sbe - Single-Bit Error\n" 371*a47a12beSStefan Roese " mbe - Multiple-Bit Error\n" 372*a47a12beSStefan Roese " mse - Memory Select Error\n" 373*a47a12beSStefan Roese " all - all errors\n" 374*a47a12beSStefan Roese "ecc injectdatahi <hi> - set Memory Data Path Error Injection Mask High\n" 375*a47a12beSStefan Roese "ecc injectdatalo <lo> - set Memory Data Path Error Injection Mask Low\n" 376*a47a12beSStefan Roese "ecc injectecc <ecc> - set ECC Error Injection Mask\n" 377*a47a12beSStefan Roese "ecc inject <en|dis> - enable/disable error injection\n" 378*a47a12beSStefan Roese "ecc mirror <en|dis> - enable/disable mirror byte\n" 379*a47a12beSStefan Roese "ecc testdw <addr> <cnt> - test mem region with double word access:\n" 380*a47a12beSStefan Roese " - enables injects\n" 381*a47a12beSStefan Roese " - writes pattern injecting errors with double word access\n" 382*a47a12beSStefan Roese " - disables injects\n" 383*a47a12beSStefan Roese " - reads pattern back with double word access, generates error\n" 384*a47a12beSStefan Roese " - re-inits memory\n" 385*a47a12beSStefan Roese "ecc testword <addr> <cnt> - test mem region with word access:\n" 386*a47a12beSStefan Roese " - enables injects\n" 387*a47a12beSStefan Roese " - writes pattern injecting errors with word access\n" 388*a47a12beSStefan Roese " - writes pattern with word access, generates error\n" 389*a47a12beSStefan Roese " - disables injects\n" " - re-inits memory"); 390*a47a12beSStefan Roese #endif 391