1*2e192b24SSimon Glass /* 2*2e192b24SSimon Glass * (C) Copyright 2000 3*2e192b24SSimon Glass * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4*2e192b24SSimon Glass * 5*2e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 6*2e192b24SSimon Glass */ 7*2e192b24SSimon Glass 8*2e192b24SSimon Glass /* 9*2e192b24SSimon Glass * Memory Functions 10*2e192b24SSimon Glass * 11*2e192b24SSimon Glass * Copied from FADS ROM, Dan Malek (dmalek@jlc.net) 12*2e192b24SSimon Glass */ 13*2e192b24SSimon Glass 14*2e192b24SSimon Glass #include <common.h> 15*2e192b24SSimon Glass #include <console.h> 16*2e192b24SSimon Glass #include <bootretry.h> 17*2e192b24SSimon Glass #include <cli.h> 18*2e192b24SSimon Glass #include <command.h> 19*2e192b24SSimon Glass #include <console.h> 20*2e192b24SSimon Glass #ifdef CONFIG_HAS_DATAFLASH 21*2e192b24SSimon Glass #include <dataflash.h> 22*2e192b24SSimon Glass #endif 23*2e192b24SSimon Glass #include <hash.h> 24*2e192b24SSimon Glass #include <inttypes.h> 25*2e192b24SSimon Glass #include <mapmem.h> 26*2e192b24SSimon Glass #include <watchdog.h> 27*2e192b24SSimon Glass #include <asm/io.h> 28*2e192b24SSimon Glass #include <linux/compiler.h> 29*2e192b24SSimon Glass 30*2e192b24SSimon Glass DECLARE_GLOBAL_DATA_PTR; 31*2e192b24SSimon Glass 32*2e192b24SSimon Glass #ifndef CONFIG_SYS_MEMTEST_SCRATCH 33*2e192b24SSimon Glass #define CONFIG_SYS_MEMTEST_SCRATCH 0 34*2e192b24SSimon Glass #endif 35*2e192b24SSimon Glass 36*2e192b24SSimon Glass static int mod_mem(cmd_tbl_t *, int, int, int, char * const []); 37*2e192b24SSimon Glass 38*2e192b24SSimon Glass /* Display values from last command. 39*2e192b24SSimon Glass * Memory modify remembered values are different from display memory. 40*2e192b24SSimon Glass */ 41*2e192b24SSimon Glass static ulong dp_last_addr, dp_last_size; 42*2e192b24SSimon Glass static ulong dp_last_length = 0x40; 43*2e192b24SSimon Glass static ulong mm_last_addr, mm_last_size; 44*2e192b24SSimon Glass 45*2e192b24SSimon Glass static ulong base_address = 0; 46*2e192b24SSimon Glass 47*2e192b24SSimon Glass /* Memory Display 48*2e192b24SSimon Glass * 49*2e192b24SSimon Glass * Syntax: 50*2e192b24SSimon Glass * md{.b, .w, .l, .q} {addr} {len} 51*2e192b24SSimon Glass */ 52*2e192b24SSimon Glass #define DISP_LINE_LEN 16 53*2e192b24SSimon Glass static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 54*2e192b24SSimon Glass { 55*2e192b24SSimon Glass ulong addr, length; 56*2e192b24SSimon Glass #if defined(CONFIG_HAS_DATAFLASH) 57*2e192b24SSimon Glass ulong nbytes, linebytes; 58*2e192b24SSimon Glass #endif 59*2e192b24SSimon Glass int size; 60*2e192b24SSimon Glass int rc = 0; 61*2e192b24SSimon Glass 62*2e192b24SSimon Glass /* We use the last specified parameters, unless new ones are 63*2e192b24SSimon Glass * entered. 64*2e192b24SSimon Glass */ 65*2e192b24SSimon Glass addr = dp_last_addr; 66*2e192b24SSimon Glass size = dp_last_size; 67*2e192b24SSimon Glass length = dp_last_length; 68*2e192b24SSimon Glass 69*2e192b24SSimon Glass if (argc < 2) 70*2e192b24SSimon Glass return CMD_RET_USAGE; 71*2e192b24SSimon Glass 72*2e192b24SSimon Glass if ((flag & CMD_FLAG_REPEAT) == 0) { 73*2e192b24SSimon Glass /* New command specified. Check for a size specification. 74*2e192b24SSimon Glass * Defaults to long if no or incorrect specification. 75*2e192b24SSimon Glass */ 76*2e192b24SSimon Glass if ((size = cmd_get_data_size(argv[0], 4)) < 0) 77*2e192b24SSimon Glass return 1; 78*2e192b24SSimon Glass 79*2e192b24SSimon Glass /* Address is specified since argc > 1 80*2e192b24SSimon Glass */ 81*2e192b24SSimon Glass addr = simple_strtoul(argv[1], NULL, 16); 82*2e192b24SSimon Glass addr += base_address; 83*2e192b24SSimon Glass 84*2e192b24SSimon Glass /* If another parameter, it is the length to display. 85*2e192b24SSimon Glass * Length is the number of objects, not number of bytes. 86*2e192b24SSimon Glass */ 87*2e192b24SSimon Glass if (argc > 2) 88*2e192b24SSimon Glass length = simple_strtoul(argv[2], NULL, 16); 89*2e192b24SSimon Glass } 90*2e192b24SSimon Glass 91*2e192b24SSimon Glass #if defined(CONFIG_HAS_DATAFLASH) 92*2e192b24SSimon Glass /* Print the lines. 93*2e192b24SSimon Glass * 94*2e192b24SSimon Glass * We buffer all read data, so we can make sure data is read only 95*2e192b24SSimon Glass * once, and all accesses are with the specified bus width. 96*2e192b24SSimon Glass */ 97*2e192b24SSimon Glass nbytes = length * size; 98*2e192b24SSimon Glass do { 99*2e192b24SSimon Glass char linebuf[DISP_LINE_LEN]; 100*2e192b24SSimon Glass void* p; 101*2e192b24SSimon Glass linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes; 102*2e192b24SSimon Glass 103*2e192b24SSimon Glass rc = read_dataflash(addr, (linebytes/size)*size, linebuf); 104*2e192b24SSimon Glass p = (rc == DATAFLASH_OK) ? linebuf : (void*)addr; 105*2e192b24SSimon Glass print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size); 106*2e192b24SSimon Glass 107*2e192b24SSimon Glass nbytes -= linebytes; 108*2e192b24SSimon Glass addr += linebytes; 109*2e192b24SSimon Glass if (ctrlc()) { 110*2e192b24SSimon Glass rc = 1; 111*2e192b24SSimon Glass break; 112*2e192b24SSimon Glass } 113*2e192b24SSimon Glass } while (nbytes > 0); 114*2e192b24SSimon Glass #else 115*2e192b24SSimon Glass 116*2e192b24SSimon Glass # if defined(CONFIG_BLACKFIN) 117*2e192b24SSimon Glass /* See if we're trying to display L1 inst */ 118*2e192b24SSimon Glass if (addr_bfin_on_chip_mem(addr)) { 119*2e192b24SSimon Glass char linebuf[DISP_LINE_LEN]; 120*2e192b24SSimon Glass ulong linebytes, nbytes = length * size; 121*2e192b24SSimon Glass do { 122*2e192b24SSimon Glass linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; 123*2e192b24SSimon Glass memcpy(linebuf, (void *)addr, linebytes); 124*2e192b24SSimon Glass print_buffer(addr, linebuf, size, linebytes/size, DISP_LINE_LEN/size); 125*2e192b24SSimon Glass 126*2e192b24SSimon Glass nbytes -= linebytes; 127*2e192b24SSimon Glass addr += linebytes; 128*2e192b24SSimon Glass if (ctrlc()) { 129*2e192b24SSimon Glass rc = 1; 130*2e192b24SSimon Glass break; 131*2e192b24SSimon Glass } 132*2e192b24SSimon Glass } while (nbytes > 0); 133*2e192b24SSimon Glass } else 134*2e192b24SSimon Glass # endif 135*2e192b24SSimon Glass 136*2e192b24SSimon Glass { 137*2e192b24SSimon Glass ulong bytes = size * length; 138*2e192b24SSimon Glass const void *buf = map_sysmem(addr, bytes); 139*2e192b24SSimon Glass 140*2e192b24SSimon Glass /* Print the lines. */ 141*2e192b24SSimon Glass print_buffer(addr, buf, size, length, DISP_LINE_LEN / size); 142*2e192b24SSimon Glass addr += bytes; 143*2e192b24SSimon Glass unmap_sysmem(buf); 144*2e192b24SSimon Glass } 145*2e192b24SSimon Glass #endif 146*2e192b24SSimon Glass 147*2e192b24SSimon Glass dp_last_addr = addr; 148*2e192b24SSimon Glass dp_last_length = length; 149*2e192b24SSimon Glass dp_last_size = size; 150*2e192b24SSimon Glass return (rc); 151*2e192b24SSimon Glass } 152*2e192b24SSimon Glass 153*2e192b24SSimon Glass static int do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 154*2e192b24SSimon Glass { 155*2e192b24SSimon Glass return mod_mem (cmdtp, 1, flag, argc, argv); 156*2e192b24SSimon Glass } 157*2e192b24SSimon Glass static int do_mem_nm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 158*2e192b24SSimon Glass { 159*2e192b24SSimon Glass return mod_mem (cmdtp, 0, flag, argc, argv); 160*2e192b24SSimon Glass } 161*2e192b24SSimon Glass 162*2e192b24SSimon Glass static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 163*2e192b24SSimon Glass { 164*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 165*2e192b24SSimon Glass u64 writeval; 166*2e192b24SSimon Glass #else 167*2e192b24SSimon Glass ulong writeval; 168*2e192b24SSimon Glass #endif 169*2e192b24SSimon Glass ulong addr, count; 170*2e192b24SSimon Glass int size; 171*2e192b24SSimon Glass void *buf, *start; 172*2e192b24SSimon Glass ulong bytes; 173*2e192b24SSimon Glass 174*2e192b24SSimon Glass if ((argc < 3) || (argc > 4)) 175*2e192b24SSimon Glass return CMD_RET_USAGE; 176*2e192b24SSimon Glass 177*2e192b24SSimon Glass /* Check for size specification. 178*2e192b24SSimon Glass */ 179*2e192b24SSimon Glass if ((size = cmd_get_data_size(argv[0], 4)) < 1) 180*2e192b24SSimon Glass return 1; 181*2e192b24SSimon Glass 182*2e192b24SSimon Glass /* Address is specified since argc > 1 183*2e192b24SSimon Glass */ 184*2e192b24SSimon Glass addr = simple_strtoul(argv[1], NULL, 16); 185*2e192b24SSimon Glass addr += base_address; 186*2e192b24SSimon Glass 187*2e192b24SSimon Glass /* Get the value to write. 188*2e192b24SSimon Glass */ 189*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 190*2e192b24SSimon Glass writeval = simple_strtoull(argv[2], NULL, 16); 191*2e192b24SSimon Glass #else 192*2e192b24SSimon Glass writeval = simple_strtoul(argv[2], NULL, 16); 193*2e192b24SSimon Glass #endif 194*2e192b24SSimon Glass 195*2e192b24SSimon Glass /* Count ? */ 196*2e192b24SSimon Glass if (argc == 4) { 197*2e192b24SSimon Glass count = simple_strtoul(argv[3], NULL, 16); 198*2e192b24SSimon Glass } else { 199*2e192b24SSimon Glass count = 1; 200*2e192b24SSimon Glass } 201*2e192b24SSimon Glass 202*2e192b24SSimon Glass bytes = size * count; 203*2e192b24SSimon Glass start = map_sysmem(addr, bytes); 204*2e192b24SSimon Glass buf = start; 205*2e192b24SSimon Glass while (count-- > 0) { 206*2e192b24SSimon Glass if (size == 4) 207*2e192b24SSimon Glass *((u32 *)buf) = (u32)writeval; 208*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 209*2e192b24SSimon Glass else if (size == 8) 210*2e192b24SSimon Glass *((u64 *)buf) = (u64)writeval; 211*2e192b24SSimon Glass #endif 212*2e192b24SSimon Glass else if (size == 2) 213*2e192b24SSimon Glass *((u16 *)buf) = (u16)writeval; 214*2e192b24SSimon Glass else 215*2e192b24SSimon Glass *((u8 *)buf) = (u8)writeval; 216*2e192b24SSimon Glass buf += size; 217*2e192b24SSimon Glass } 218*2e192b24SSimon Glass unmap_sysmem(start); 219*2e192b24SSimon Glass return 0; 220*2e192b24SSimon Glass } 221*2e192b24SSimon Glass 222*2e192b24SSimon Glass #ifdef CONFIG_MX_CYCLIC 223*2e192b24SSimon Glass static int do_mem_mdc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 224*2e192b24SSimon Glass { 225*2e192b24SSimon Glass int i; 226*2e192b24SSimon Glass ulong count; 227*2e192b24SSimon Glass 228*2e192b24SSimon Glass if (argc < 4) 229*2e192b24SSimon Glass return CMD_RET_USAGE; 230*2e192b24SSimon Glass 231*2e192b24SSimon Glass count = simple_strtoul(argv[3], NULL, 10); 232*2e192b24SSimon Glass 233*2e192b24SSimon Glass for (;;) { 234*2e192b24SSimon Glass do_mem_md (NULL, 0, 3, argv); 235*2e192b24SSimon Glass 236*2e192b24SSimon Glass /* delay for <count> ms... */ 237*2e192b24SSimon Glass for (i=0; i<count; i++) 238*2e192b24SSimon Glass udelay (1000); 239*2e192b24SSimon Glass 240*2e192b24SSimon Glass /* check for ctrl-c to abort... */ 241*2e192b24SSimon Glass if (ctrlc()) { 242*2e192b24SSimon Glass puts("Abort\n"); 243*2e192b24SSimon Glass return 0; 244*2e192b24SSimon Glass } 245*2e192b24SSimon Glass } 246*2e192b24SSimon Glass 247*2e192b24SSimon Glass return 0; 248*2e192b24SSimon Glass } 249*2e192b24SSimon Glass 250*2e192b24SSimon Glass static int do_mem_mwc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 251*2e192b24SSimon Glass { 252*2e192b24SSimon Glass int i; 253*2e192b24SSimon Glass ulong count; 254*2e192b24SSimon Glass 255*2e192b24SSimon Glass if (argc < 4) 256*2e192b24SSimon Glass return CMD_RET_USAGE; 257*2e192b24SSimon Glass 258*2e192b24SSimon Glass count = simple_strtoul(argv[3], NULL, 10); 259*2e192b24SSimon Glass 260*2e192b24SSimon Glass for (;;) { 261*2e192b24SSimon Glass do_mem_mw (NULL, 0, 3, argv); 262*2e192b24SSimon Glass 263*2e192b24SSimon Glass /* delay for <count> ms... */ 264*2e192b24SSimon Glass for (i=0; i<count; i++) 265*2e192b24SSimon Glass udelay (1000); 266*2e192b24SSimon Glass 267*2e192b24SSimon Glass /* check for ctrl-c to abort... */ 268*2e192b24SSimon Glass if (ctrlc()) { 269*2e192b24SSimon Glass puts("Abort\n"); 270*2e192b24SSimon Glass return 0; 271*2e192b24SSimon Glass } 272*2e192b24SSimon Glass } 273*2e192b24SSimon Glass 274*2e192b24SSimon Glass return 0; 275*2e192b24SSimon Glass } 276*2e192b24SSimon Glass #endif /* CONFIG_MX_CYCLIC */ 277*2e192b24SSimon Glass 278*2e192b24SSimon Glass static int do_mem_cmp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 279*2e192b24SSimon Glass { 280*2e192b24SSimon Glass ulong addr1, addr2, count, ngood, bytes; 281*2e192b24SSimon Glass int size; 282*2e192b24SSimon Glass int rcode = 0; 283*2e192b24SSimon Glass const char *type; 284*2e192b24SSimon Glass const void *buf1, *buf2, *base; 285*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 286*2e192b24SSimon Glass u64 word1, word2; 287*2e192b24SSimon Glass #else 288*2e192b24SSimon Glass ulong word1, word2; 289*2e192b24SSimon Glass #endif 290*2e192b24SSimon Glass 291*2e192b24SSimon Glass if (argc != 4) 292*2e192b24SSimon Glass return CMD_RET_USAGE; 293*2e192b24SSimon Glass 294*2e192b24SSimon Glass /* Check for size specification. 295*2e192b24SSimon Glass */ 296*2e192b24SSimon Glass if ((size = cmd_get_data_size(argv[0], 4)) < 0) 297*2e192b24SSimon Glass return 1; 298*2e192b24SSimon Glass type = size == 8 ? "double word" : 299*2e192b24SSimon Glass size == 4 ? "word" : 300*2e192b24SSimon Glass size == 2 ? "halfword" : "byte"; 301*2e192b24SSimon Glass 302*2e192b24SSimon Glass addr1 = simple_strtoul(argv[1], NULL, 16); 303*2e192b24SSimon Glass addr1 += base_address; 304*2e192b24SSimon Glass 305*2e192b24SSimon Glass addr2 = simple_strtoul(argv[2], NULL, 16); 306*2e192b24SSimon Glass addr2 += base_address; 307*2e192b24SSimon Glass 308*2e192b24SSimon Glass count = simple_strtoul(argv[3], NULL, 16); 309*2e192b24SSimon Glass 310*2e192b24SSimon Glass #ifdef CONFIG_HAS_DATAFLASH 311*2e192b24SSimon Glass if (addr_dataflash(addr1) | addr_dataflash(addr2)){ 312*2e192b24SSimon Glass puts ("Comparison with DataFlash space not supported.\n\r"); 313*2e192b24SSimon Glass return 0; 314*2e192b24SSimon Glass } 315*2e192b24SSimon Glass #endif 316*2e192b24SSimon Glass 317*2e192b24SSimon Glass #ifdef CONFIG_BLACKFIN 318*2e192b24SSimon Glass if (addr_bfin_on_chip_mem(addr1) || addr_bfin_on_chip_mem(addr2)) { 319*2e192b24SSimon Glass puts ("Comparison with L1 instruction memory not supported.\n\r"); 320*2e192b24SSimon Glass return 0; 321*2e192b24SSimon Glass } 322*2e192b24SSimon Glass #endif 323*2e192b24SSimon Glass 324*2e192b24SSimon Glass bytes = size * count; 325*2e192b24SSimon Glass base = buf1 = map_sysmem(addr1, bytes); 326*2e192b24SSimon Glass buf2 = map_sysmem(addr2, bytes); 327*2e192b24SSimon Glass for (ngood = 0; ngood < count; ++ngood) { 328*2e192b24SSimon Glass if (size == 4) { 329*2e192b24SSimon Glass word1 = *(u32 *)buf1; 330*2e192b24SSimon Glass word2 = *(u32 *)buf2; 331*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 332*2e192b24SSimon Glass } else if (size == 8) { 333*2e192b24SSimon Glass word1 = *(u64 *)buf1; 334*2e192b24SSimon Glass word2 = *(u64 *)buf2; 335*2e192b24SSimon Glass #endif 336*2e192b24SSimon Glass } else if (size == 2) { 337*2e192b24SSimon Glass word1 = *(u16 *)buf1; 338*2e192b24SSimon Glass word2 = *(u16 *)buf2; 339*2e192b24SSimon Glass } else { 340*2e192b24SSimon Glass word1 = *(u8 *)buf1; 341*2e192b24SSimon Glass word2 = *(u8 *)buf2; 342*2e192b24SSimon Glass } 343*2e192b24SSimon Glass if (word1 != word2) { 344*2e192b24SSimon Glass ulong offset = buf1 - base; 345*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 346*2e192b24SSimon Glass printf("%s at 0x%p (%#0*"PRIx64") != %s at 0x%p (%#0*" 347*2e192b24SSimon Glass PRIx64 ")\n", 348*2e192b24SSimon Glass type, (void *)(addr1 + offset), size, word1, 349*2e192b24SSimon Glass type, (void *)(addr2 + offset), size, word2); 350*2e192b24SSimon Glass #else 351*2e192b24SSimon Glass printf("%s at 0x%08lx (%#0*lx) != %s at 0x%08lx (%#0*lx)\n", 352*2e192b24SSimon Glass type, (ulong)(addr1 + offset), size, word1, 353*2e192b24SSimon Glass type, (ulong)(addr2 + offset), size, word2); 354*2e192b24SSimon Glass #endif 355*2e192b24SSimon Glass rcode = 1; 356*2e192b24SSimon Glass break; 357*2e192b24SSimon Glass } 358*2e192b24SSimon Glass 359*2e192b24SSimon Glass buf1 += size; 360*2e192b24SSimon Glass buf2 += size; 361*2e192b24SSimon Glass 362*2e192b24SSimon Glass /* reset watchdog from time to time */ 363*2e192b24SSimon Glass if ((ngood % (64 << 10)) == 0) 364*2e192b24SSimon Glass WATCHDOG_RESET(); 365*2e192b24SSimon Glass } 366*2e192b24SSimon Glass unmap_sysmem(buf1); 367*2e192b24SSimon Glass unmap_sysmem(buf2); 368*2e192b24SSimon Glass 369*2e192b24SSimon Glass printf("Total of %ld %s(s) were the same\n", ngood, type); 370*2e192b24SSimon Glass return rcode; 371*2e192b24SSimon Glass } 372*2e192b24SSimon Glass 373*2e192b24SSimon Glass static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 374*2e192b24SSimon Glass { 375*2e192b24SSimon Glass ulong addr, dest, count, bytes; 376*2e192b24SSimon Glass int size; 377*2e192b24SSimon Glass const void *src; 378*2e192b24SSimon Glass void *buf; 379*2e192b24SSimon Glass 380*2e192b24SSimon Glass if (argc != 4) 381*2e192b24SSimon Glass return CMD_RET_USAGE; 382*2e192b24SSimon Glass 383*2e192b24SSimon Glass /* Check for size specification. 384*2e192b24SSimon Glass */ 385*2e192b24SSimon Glass if ((size = cmd_get_data_size(argv[0], 4)) < 0) 386*2e192b24SSimon Glass return 1; 387*2e192b24SSimon Glass 388*2e192b24SSimon Glass addr = simple_strtoul(argv[1], NULL, 16); 389*2e192b24SSimon Glass addr += base_address; 390*2e192b24SSimon Glass 391*2e192b24SSimon Glass dest = simple_strtoul(argv[2], NULL, 16); 392*2e192b24SSimon Glass dest += base_address; 393*2e192b24SSimon Glass 394*2e192b24SSimon Glass count = simple_strtoul(argv[3], NULL, 16); 395*2e192b24SSimon Glass 396*2e192b24SSimon Glass if (count == 0) { 397*2e192b24SSimon Glass puts ("Zero length ???\n"); 398*2e192b24SSimon Glass return 1; 399*2e192b24SSimon Glass } 400*2e192b24SSimon Glass 401*2e192b24SSimon Glass #ifndef CONFIG_SYS_NO_FLASH 402*2e192b24SSimon Glass /* check if we are copying to Flash */ 403*2e192b24SSimon Glass if ( (addr2info(dest) != NULL) 404*2e192b24SSimon Glass #ifdef CONFIG_HAS_DATAFLASH 405*2e192b24SSimon Glass && (!addr_dataflash(dest)) 406*2e192b24SSimon Glass #endif 407*2e192b24SSimon Glass ) { 408*2e192b24SSimon Glass int rc; 409*2e192b24SSimon Glass 410*2e192b24SSimon Glass puts ("Copy to Flash... "); 411*2e192b24SSimon Glass 412*2e192b24SSimon Glass rc = flash_write ((char *)addr, dest, count*size); 413*2e192b24SSimon Glass if (rc != 0) { 414*2e192b24SSimon Glass flash_perror (rc); 415*2e192b24SSimon Glass return (1); 416*2e192b24SSimon Glass } 417*2e192b24SSimon Glass puts ("done\n"); 418*2e192b24SSimon Glass return 0; 419*2e192b24SSimon Glass } 420*2e192b24SSimon Glass #endif 421*2e192b24SSimon Glass 422*2e192b24SSimon Glass #ifdef CONFIG_HAS_DATAFLASH 423*2e192b24SSimon Glass /* Check if we are copying from RAM or Flash to DataFlash */ 424*2e192b24SSimon Glass if (addr_dataflash(dest) && !addr_dataflash(addr)){ 425*2e192b24SSimon Glass int rc; 426*2e192b24SSimon Glass 427*2e192b24SSimon Glass puts ("Copy to DataFlash... "); 428*2e192b24SSimon Glass 429*2e192b24SSimon Glass rc = write_dataflash (dest, addr, count*size); 430*2e192b24SSimon Glass 431*2e192b24SSimon Glass if (rc != 1) { 432*2e192b24SSimon Glass dataflash_perror (rc); 433*2e192b24SSimon Glass return (1); 434*2e192b24SSimon Glass } 435*2e192b24SSimon Glass puts ("done\n"); 436*2e192b24SSimon Glass return 0; 437*2e192b24SSimon Glass } 438*2e192b24SSimon Glass 439*2e192b24SSimon Glass /* Check if we are copying from DataFlash to RAM */ 440*2e192b24SSimon Glass if (addr_dataflash(addr) && !addr_dataflash(dest) 441*2e192b24SSimon Glass #ifndef CONFIG_SYS_NO_FLASH 442*2e192b24SSimon Glass && (addr2info(dest) == NULL) 443*2e192b24SSimon Glass #endif 444*2e192b24SSimon Glass ){ 445*2e192b24SSimon Glass int rc; 446*2e192b24SSimon Glass rc = read_dataflash(addr, count * size, (char *) dest); 447*2e192b24SSimon Glass if (rc != 1) { 448*2e192b24SSimon Glass dataflash_perror (rc); 449*2e192b24SSimon Glass return (1); 450*2e192b24SSimon Glass } 451*2e192b24SSimon Glass return 0; 452*2e192b24SSimon Glass } 453*2e192b24SSimon Glass 454*2e192b24SSimon Glass if (addr_dataflash(addr) && addr_dataflash(dest)){ 455*2e192b24SSimon Glass puts ("Unsupported combination of source/destination.\n\r"); 456*2e192b24SSimon Glass return 1; 457*2e192b24SSimon Glass } 458*2e192b24SSimon Glass #endif 459*2e192b24SSimon Glass 460*2e192b24SSimon Glass #ifdef CONFIG_BLACKFIN 461*2e192b24SSimon Glass /* See if we're copying to/from L1 inst */ 462*2e192b24SSimon Glass if (addr_bfin_on_chip_mem(dest) || addr_bfin_on_chip_mem(addr)) { 463*2e192b24SSimon Glass memcpy((void *)dest, (void *)addr, count * size); 464*2e192b24SSimon Glass return 0; 465*2e192b24SSimon Glass } 466*2e192b24SSimon Glass #endif 467*2e192b24SSimon Glass 468*2e192b24SSimon Glass bytes = size * count; 469*2e192b24SSimon Glass buf = map_sysmem(dest, bytes); 470*2e192b24SSimon Glass src = map_sysmem(addr, bytes); 471*2e192b24SSimon Glass while (count-- > 0) { 472*2e192b24SSimon Glass if (size == 4) 473*2e192b24SSimon Glass *((u32 *)buf) = *((u32 *)src); 474*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 475*2e192b24SSimon Glass else if (size == 8) 476*2e192b24SSimon Glass *((u64 *)buf) = *((u64 *)src); 477*2e192b24SSimon Glass #endif 478*2e192b24SSimon Glass else if (size == 2) 479*2e192b24SSimon Glass *((u16 *)buf) = *((u16 *)src); 480*2e192b24SSimon Glass else 481*2e192b24SSimon Glass *((u8 *)buf) = *((u8 *)src); 482*2e192b24SSimon Glass src += size; 483*2e192b24SSimon Glass buf += size; 484*2e192b24SSimon Glass 485*2e192b24SSimon Glass /* reset watchdog from time to time */ 486*2e192b24SSimon Glass if ((count % (64 << 10)) == 0) 487*2e192b24SSimon Glass WATCHDOG_RESET(); 488*2e192b24SSimon Glass } 489*2e192b24SSimon Glass unmap_sysmem(buf); 490*2e192b24SSimon Glass unmap_sysmem(src); 491*2e192b24SSimon Glass 492*2e192b24SSimon Glass return 0; 493*2e192b24SSimon Glass } 494*2e192b24SSimon Glass 495*2e192b24SSimon Glass static int do_mem_base(cmd_tbl_t *cmdtp, int flag, int argc, 496*2e192b24SSimon Glass char * const argv[]) 497*2e192b24SSimon Glass { 498*2e192b24SSimon Glass if (argc > 1) { 499*2e192b24SSimon Glass /* Set new base address. 500*2e192b24SSimon Glass */ 501*2e192b24SSimon Glass base_address = simple_strtoul(argv[1], NULL, 16); 502*2e192b24SSimon Glass } 503*2e192b24SSimon Glass /* Print the current base address. 504*2e192b24SSimon Glass */ 505*2e192b24SSimon Glass printf("Base Address: 0x%08lx\n", base_address); 506*2e192b24SSimon Glass return 0; 507*2e192b24SSimon Glass } 508*2e192b24SSimon Glass 509*2e192b24SSimon Glass static int do_mem_loop(cmd_tbl_t *cmdtp, int flag, int argc, 510*2e192b24SSimon Glass char * const argv[]) 511*2e192b24SSimon Glass { 512*2e192b24SSimon Glass ulong addr, length, i, bytes; 513*2e192b24SSimon Glass int size; 514*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 515*2e192b24SSimon Glass volatile u64 *llp; 516*2e192b24SSimon Glass #endif 517*2e192b24SSimon Glass volatile u32 *longp; 518*2e192b24SSimon Glass volatile u16 *shortp; 519*2e192b24SSimon Glass volatile u8 *cp; 520*2e192b24SSimon Glass const void *buf; 521*2e192b24SSimon Glass 522*2e192b24SSimon Glass if (argc < 3) 523*2e192b24SSimon Glass return CMD_RET_USAGE; 524*2e192b24SSimon Glass 525*2e192b24SSimon Glass /* 526*2e192b24SSimon Glass * Check for a size specification. 527*2e192b24SSimon Glass * Defaults to long if no or incorrect specification. 528*2e192b24SSimon Glass */ 529*2e192b24SSimon Glass if ((size = cmd_get_data_size(argv[0], 4)) < 0) 530*2e192b24SSimon Glass return 1; 531*2e192b24SSimon Glass 532*2e192b24SSimon Glass /* Address is always specified. 533*2e192b24SSimon Glass */ 534*2e192b24SSimon Glass addr = simple_strtoul(argv[1], NULL, 16); 535*2e192b24SSimon Glass 536*2e192b24SSimon Glass /* Length is the number of objects, not number of bytes. 537*2e192b24SSimon Glass */ 538*2e192b24SSimon Glass length = simple_strtoul(argv[2], NULL, 16); 539*2e192b24SSimon Glass 540*2e192b24SSimon Glass bytes = size * length; 541*2e192b24SSimon Glass buf = map_sysmem(addr, bytes); 542*2e192b24SSimon Glass 543*2e192b24SSimon Glass /* We want to optimize the loops to run as fast as possible. 544*2e192b24SSimon Glass * If we have only one object, just run infinite loops. 545*2e192b24SSimon Glass */ 546*2e192b24SSimon Glass if (length == 1) { 547*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 548*2e192b24SSimon Glass if (size == 8) { 549*2e192b24SSimon Glass llp = (u64 *)buf; 550*2e192b24SSimon Glass for (;;) 551*2e192b24SSimon Glass i = *llp; 552*2e192b24SSimon Glass } 553*2e192b24SSimon Glass #endif 554*2e192b24SSimon Glass if (size == 4) { 555*2e192b24SSimon Glass longp = (u32 *)buf; 556*2e192b24SSimon Glass for (;;) 557*2e192b24SSimon Glass i = *longp; 558*2e192b24SSimon Glass } 559*2e192b24SSimon Glass if (size == 2) { 560*2e192b24SSimon Glass shortp = (u16 *)buf; 561*2e192b24SSimon Glass for (;;) 562*2e192b24SSimon Glass i = *shortp; 563*2e192b24SSimon Glass } 564*2e192b24SSimon Glass cp = (u8 *)buf; 565*2e192b24SSimon Glass for (;;) 566*2e192b24SSimon Glass i = *cp; 567*2e192b24SSimon Glass } 568*2e192b24SSimon Glass 569*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 570*2e192b24SSimon Glass if (size == 8) { 571*2e192b24SSimon Glass for (;;) { 572*2e192b24SSimon Glass llp = (u64 *)buf; 573*2e192b24SSimon Glass i = length; 574*2e192b24SSimon Glass while (i-- > 0) 575*2e192b24SSimon Glass *llp++; 576*2e192b24SSimon Glass } 577*2e192b24SSimon Glass } 578*2e192b24SSimon Glass #endif 579*2e192b24SSimon Glass if (size == 4) { 580*2e192b24SSimon Glass for (;;) { 581*2e192b24SSimon Glass longp = (u32 *)buf; 582*2e192b24SSimon Glass i = length; 583*2e192b24SSimon Glass while (i-- > 0) 584*2e192b24SSimon Glass *longp++; 585*2e192b24SSimon Glass } 586*2e192b24SSimon Glass } 587*2e192b24SSimon Glass if (size == 2) { 588*2e192b24SSimon Glass for (;;) { 589*2e192b24SSimon Glass shortp = (u16 *)buf; 590*2e192b24SSimon Glass i = length; 591*2e192b24SSimon Glass while (i-- > 0) 592*2e192b24SSimon Glass *shortp++; 593*2e192b24SSimon Glass } 594*2e192b24SSimon Glass } 595*2e192b24SSimon Glass for (;;) { 596*2e192b24SSimon Glass cp = (u8 *)buf; 597*2e192b24SSimon Glass i = length; 598*2e192b24SSimon Glass while (i-- > 0) 599*2e192b24SSimon Glass *cp++; 600*2e192b24SSimon Glass } 601*2e192b24SSimon Glass unmap_sysmem(buf); 602*2e192b24SSimon Glass 603*2e192b24SSimon Glass return 0; 604*2e192b24SSimon Glass } 605*2e192b24SSimon Glass 606*2e192b24SSimon Glass #ifdef CONFIG_LOOPW 607*2e192b24SSimon Glass static int do_mem_loopw(cmd_tbl_t *cmdtp, int flag, int argc, 608*2e192b24SSimon Glass char * const argv[]) 609*2e192b24SSimon Glass { 610*2e192b24SSimon Glass ulong addr, length, i, bytes; 611*2e192b24SSimon Glass int size; 612*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 613*2e192b24SSimon Glass volatile u64 *llp; 614*2e192b24SSimon Glass u64 data; 615*2e192b24SSimon Glass #else 616*2e192b24SSimon Glass ulong data; 617*2e192b24SSimon Glass #endif 618*2e192b24SSimon Glass volatile u32 *longp; 619*2e192b24SSimon Glass volatile u16 *shortp; 620*2e192b24SSimon Glass volatile u8 *cp; 621*2e192b24SSimon Glass void *buf; 622*2e192b24SSimon Glass 623*2e192b24SSimon Glass if (argc < 4) 624*2e192b24SSimon Glass return CMD_RET_USAGE; 625*2e192b24SSimon Glass 626*2e192b24SSimon Glass /* 627*2e192b24SSimon Glass * Check for a size specification. 628*2e192b24SSimon Glass * Defaults to long if no or incorrect specification. 629*2e192b24SSimon Glass */ 630*2e192b24SSimon Glass if ((size = cmd_get_data_size(argv[0], 4)) < 0) 631*2e192b24SSimon Glass return 1; 632*2e192b24SSimon Glass 633*2e192b24SSimon Glass /* Address is always specified. 634*2e192b24SSimon Glass */ 635*2e192b24SSimon Glass addr = simple_strtoul(argv[1], NULL, 16); 636*2e192b24SSimon Glass 637*2e192b24SSimon Glass /* Length is the number of objects, not number of bytes. 638*2e192b24SSimon Glass */ 639*2e192b24SSimon Glass length = simple_strtoul(argv[2], NULL, 16); 640*2e192b24SSimon Glass 641*2e192b24SSimon Glass /* data to write */ 642*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 643*2e192b24SSimon Glass data = simple_strtoull(argv[3], NULL, 16); 644*2e192b24SSimon Glass #else 645*2e192b24SSimon Glass data = simple_strtoul(argv[3], NULL, 16); 646*2e192b24SSimon Glass #endif 647*2e192b24SSimon Glass 648*2e192b24SSimon Glass bytes = size * length; 649*2e192b24SSimon Glass buf = map_sysmem(addr, bytes); 650*2e192b24SSimon Glass 651*2e192b24SSimon Glass /* We want to optimize the loops to run as fast as possible. 652*2e192b24SSimon Glass * If we have only one object, just run infinite loops. 653*2e192b24SSimon Glass */ 654*2e192b24SSimon Glass if (length == 1) { 655*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 656*2e192b24SSimon Glass if (size == 8) { 657*2e192b24SSimon Glass llp = (u64 *)buf; 658*2e192b24SSimon Glass for (;;) 659*2e192b24SSimon Glass *llp = data; 660*2e192b24SSimon Glass } 661*2e192b24SSimon Glass #endif 662*2e192b24SSimon Glass if (size == 4) { 663*2e192b24SSimon Glass longp = (u32 *)buf; 664*2e192b24SSimon Glass for (;;) 665*2e192b24SSimon Glass *longp = data; 666*2e192b24SSimon Glass } 667*2e192b24SSimon Glass if (size == 2) { 668*2e192b24SSimon Glass shortp = (u16 *)buf; 669*2e192b24SSimon Glass for (;;) 670*2e192b24SSimon Glass *shortp = data; 671*2e192b24SSimon Glass } 672*2e192b24SSimon Glass cp = (u8 *)buf; 673*2e192b24SSimon Glass for (;;) 674*2e192b24SSimon Glass *cp = data; 675*2e192b24SSimon Glass } 676*2e192b24SSimon Glass 677*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 678*2e192b24SSimon Glass if (size == 8) { 679*2e192b24SSimon Glass for (;;) { 680*2e192b24SSimon Glass llp = (u64 *)buf; 681*2e192b24SSimon Glass i = length; 682*2e192b24SSimon Glass while (i-- > 0) 683*2e192b24SSimon Glass *llp++ = data; 684*2e192b24SSimon Glass } 685*2e192b24SSimon Glass } 686*2e192b24SSimon Glass #endif 687*2e192b24SSimon Glass if (size == 4) { 688*2e192b24SSimon Glass for (;;) { 689*2e192b24SSimon Glass longp = (u32 *)buf; 690*2e192b24SSimon Glass i = length; 691*2e192b24SSimon Glass while (i-- > 0) 692*2e192b24SSimon Glass *longp++ = data; 693*2e192b24SSimon Glass } 694*2e192b24SSimon Glass } 695*2e192b24SSimon Glass if (size == 2) { 696*2e192b24SSimon Glass for (;;) { 697*2e192b24SSimon Glass shortp = (u16 *)buf; 698*2e192b24SSimon Glass i = length; 699*2e192b24SSimon Glass while (i-- > 0) 700*2e192b24SSimon Glass *shortp++ = data; 701*2e192b24SSimon Glass } 702*2e192b24SSimon Glass } 703*2e192b24SSimon Glass for (;;) { 704*2e192b24SSimon Glass cp = (u8 *)buf; 705*2e192b24SSimon Glass i = length; 706*2e192b24SSimon Glass while (i-- > 0) 707*2e192b24SSimon Glass *cp++ = data; 708*2e192b24SSimon Glass } 709*2e192b24SSimon Glass } 710*2e192b24SSimon Glass #endif /* CONFIG_LOOPW */ 711*2e192b24SSimon Glass 712*2e192b24SSimon Glass #ifdef CONFIG_CMD_MEMTEST 713*2e192b24SSimon Glass static ulong mem_test_alt(vu_long *buf, ulong start_addr, ulong end_addr, 714*2e192b24SSimon Glass vu_long *dummy) 715*2e192b24SSimon Glass { 716*2e192b24SSimon Glass vu_long *addr; 717*2e192b24SSimon Glass ulong errs = 0; 718*2e192b24SSimon Glass ulong val, readback; 719*2e192b24SSimon Glass int j; 720*2e192b24SSimon Glass vu_long offset; 721*2e192b24SSimon Glass vu_long test_offset; 722*2e192b24SSimon Glass vu_long pattern; 723*2e192b24SSimon Glass vu_long temp; 724*2e192b24SSimon Glass vu_long anti_pattern; 725*2e192b24SSimon Glass vu_long num_words; 726*2e192b24SSimon Glass static const ulong bitpattern[] = { 727*2e192b24SSimon Glass 0x00000001, /* single bit */ 728*2e192b24SSimon Glass 0x00000003, /* two adjacent bits */ 729*2e192b24SSimon Glass 0x00000007, /* three adjacent bits */ 730*2e192b24SSimon Glass 0x0000000F, /* four adjacent bits */ 731*2e192b24SSimon Glass 0x00000005, /* two non-adjacent bits */ 732*2e192b24SSimon Glass 0x00000015, /* three non-adjacent bits */ 733*2e192b24SSimon Glass 0x00000055, /* four non-adjacent bits */ 734*2e192b24SSimon Glass 0xaaaaaaaa, /* alternating 1/0 */ 735*2e192b24SSimon Glass }; 736*2e192b24SSimon Glass 737*2e192b24SSimon Glass num_words = (end_addr - start_addr) / sizeof(vu_long); 738*2e192b24SSimon Glass 739*2e192b24SSimon Glass /* 740*2e192b24SSimon Glass * Data line test: write a pattern to the first 741*2e192b24SSimon Glass * location, write the 1's complement to a 'parking' 742*2e192b24SSimon Glass * address (changes the state of the data bus so a 743*2e192b24SSimon Glass * floating bus doesn't give a false OK), and then 744*2e192b24SSimon Glass * read the value back. Note that we read it back 745*2e192b24SSimon Glass * into a variable because the next time we read it, 746*2e192b24SSimon Glass * it might be right (been there, tough to explain to 747*2e192b24SSimon Glass * the quality guys why it prints a failure when the 748*2e192b24SSimon Glass * "is" and "should be" are obviously the same in the 749*2e192b24SSimon Glass * error message). 750*2e192b24SSimon Glass * 751*2e192b24SSimon Glass * Rather than exhaustively testing, we test some 752*2e192b24SSimon Glass * patterns by shifting '1' bits through a field of 753*2e192b24SSimon Glass * '0's and '0' bits through a field of '1's (i.e. 754*2e192b24SSimon Glass * pattern and ~pattern). 755*2e192b24SSimon Glass */ 756*2e192b24SSimon Glass addr = buf; 757*2e192b24SSimon Glass for (j = 0; j < sizeof(bitpattern) / sizeof(bitpattern[0]); j++) { 758*2e192b24SSimon Glass val = bitpattern[j]; 759*2e192b24SSimon Glass for (; val != 0; val <<= 1) { 760*2e192b24SSimon Glass *addr = val; 761*2e192b24SSimon Glass *dummy = ~val; /* clear the test data off the bus */ 762*2e192b24SSimon Glass readback = *addr; 763*2e192b24SSimon Glass if (readback != val) { 764*2e192b24SSimon Glass printf("FAILURE (data line): " 765*2e192b24SSimon Glass "expected %08lx, actual %08lx\n", 766*2e192b24SSimon Glass val, readback); 767*2e192b24SSimon Glass errs++; 768*2e192b24SSimon Glass if (ctrlc()) 769*2e192b24SSimon Glass return -1; 770*2e192b24SSimon Glass } 771*2e192b24SSimon Glass *addr = ~val; 772*2e192b24SSimon Glass *dummy = val; 773*2e192b24SSimon Glass readback = *addr; 774*2e192b24SSimon Glass if (readback != ~val) { 775*2e192b24SSimon Glass printf("FAILURE (data line): " 776*2e192b24SSimon Glass "Is %08lx, should be %08lx\n", 777*2e192b24SSimon Glass readback, ~val); 778*2e192b24SSimon Glass errs++; 779*2e192b24SSimon Glass if (ctrlc()) 780*2e192b24SSimon Glass return -1; 781*2e192b24SSimon Glass } 782*2e192b24SSimon Glass } 783*2e192b24SSimon Glass } 784*2e192b24SSimon Glass 785*2e192b24SSimon Glass /* 786*2e192b24SSimon Glass * Based on code whose Original Author and Copyright 787*2e192b24SSimon Glass * information follows: Copyright (c) 1998 by Michael 788*2e192b24SSimon Glass * Barr. This software is placed into the public 789*2e192b24SSimon Glass * domain and may be used for any purpose. However, 790*2e192b24SSimon Glass * this notice must not be changed or removed and no 791*2e192b24SSimon Glass * warranty is either expressed or implied by its 792*2e192b24SSimon Glass * publication or distribution. 793*2e192b24SSimon Glass */ 794*2e192b24SSimon Glass 795*2e192b24SSimon Glass /* 796*2e192b24SSimon Glass * Address line test 797*2e192b24SSimon Glass 798*2e192b24SSimon Glass * Description: Test the address bus wiring in a 799*2e192b24SSimon Glass * memory region by performing a walking 800*2e192b24SSimon Glass * 1's test on the relevant bits of the 801*2e192b24SSimon Glass * address and checking for aliasing. 802*2e192b24SSimon Glass * This test will find single-bit 803*2e192b24SSimon Glass * address failures such as stuck-high, 804*2e192b24SSimon Glass * stuck-low, and shorted pins. The base 805*2e192b24SSimon Glass * address and size of the region are 806*2e192b24SSimon Glass * selected by the caller. 807*2e192b24SSimon Glass 808*2e192b24SSimon Glass * Notes: For best results, the selected base 809*2e192b24SSimon Glass * address should have enough LSB 0's to 810*2e192b24SSimon Glass * guarantee single address bit changes. 811*2e192b24SSimon Glass * For example, to test a 64-Kbyte 812*2e192b24SSimon Glass * region, select a base address on a 813*2e192b24SSimon Glass * 64-Kbyte boundary. Also, select the 814*2e192b24SSimon Glass * region size as a power-of-two if at 815*2e192b24SSimon Glass * all possible. 816*2e192b24SSimon Glass * 817*2e192b24SSimon Glass * Returns: 0 if the test succeeds, 1 if the test fails. 818*2e192b24SSimon Glass */ 819*2e192b24SSimon Glass pattern = (vu_long) 0xaaaaaaaa; 820*2e192b24SSimon Glass anti_pattern = (vu_long) 0x55555555; 821*2e192b24SSimon Glass 822*2e192b24SSimon Glass debug("%s:%d: length = 0x%.8lx\n", __func__, __LINE__, num_words); 823*2e192b24SSimon Glass /* 824*2e192b24SSimon Glass * Write the default pattern at each of the 825*2e192b24SSimon Glass * power-of-two offsets. 826*2e192b24SSimon Glass */ 827*2e192b24SSimon Glass for (offset = 1; offset < num_words; offset <<= 1) 828*2e192b24SSimon Glass addr[offset] = pattern; 829*2e192b24SSimon Glass 830*2e192b24SSimon Glass /* 831*2e192b24SSimon Glass * Check for address bits stuck high. 832*2e192b24SSimon Glass */ 833*2e192b24SSimon Glass test_offset = 0; 834*2e192b24SSimon Glass addr[test_offset] = anti_pattern; 835*2e192b24SSimon Glass 836*2e192b24SSimon Glass for (offset = 1; offset < num_words; offset <<= 1) { 837*2e192b24SSimon Glass temp = addr[offset]; 838*2e192b24SSimon Glass if (temp != pattern) { 839*2e192b24SSimon Glass printf("\nFAILURE: Address bit stuck high @ 0x%.8lx:" 840*2e192b24SSimon Glass " expected 0x%.8lx, actual 0x%.8lx\n", 841*2e192b24SSimon Glass start_addr + offset*sizeof(vu_long), 842*2e192b24SSimon Glass pattern, temp); 843*2e192b24SSimon Glass errs++; 844*2e192b24SSimon Glass if (ctrlc()) 845*2e192b24SSimon Glass return -1; 846*2e192b24SSimon Glass } 847*2e192b24SSimon Glass } 848*2e192b24SSimon Glass addr[test_offset] = pattern; 849*2e192b24SSimon Glass WATCHDOG_RESET(); 850*2e192b24SSimon Glass 851*2e192b24SSimon Glass /* 852*2e192b24SSimon Glass * Check for addr bits stuck low or shorted. 853*2e192b24SSimon Glass */ 854*2e192b24SSimon Glass for (test_offset = 1; test_offset < num_words; test_offset <<= 1) { 855*2e192b24SSimon Glass addr[test_offset] = anti_pattern; 856*2e192b24SSimon Glass 857*2e192b24SSimon Glass for (offset = 1; offset < num_words; offset <<= 1) { 858*2e192b24SSimon Glass temp = addr[offset]; 859*2e192b24SSimon Glass if ((temp != pattern) && (offset != test_offset)) { 860*2e192b24SSimon Glass printf("\nFAILURE: Address bit stuck low or" 861*2e192b24SSimon Glass " shorted @ 0x%.8lx: expected 0x%.8lx," 862*2e192b24SSimon Glass " actual 0x%.8lx\n", 863*2e192b24SSimon Glass start_addr + offset*sizeof(vu_long), 864*2e192b24SSimon Glass pattern, temp); 865*2e192b24SSimon Glass errs++; 866*2e192b24SSimon Glass if (ctrlc()) 867*2e192b24SSimon Glass return -1; 868*2e192b24SSimon Glass } 869*2e192b24SSimon Glass } 870*2e192b24SSimon Glass addr[test_offset] = pattern; 871*2e192b24SSimon Glass } 872*2e192b24SSimon Glass 873*2e192b24SSimon Glass /* 874*2e192b24SSimon Glass * Description: Test the integrity of a physical 875*2e192b24SSimon Glass * memory device by performing an 876*2e192b24SSimon Glass * increment/decrement test over the 877*2e192b24SSimon Glass * entire region. In the process every 878*2e192b24SSimon Glass * storage bit in the device is tested 879*2e192b24SSimon Glass * as a zero and a one. The base address 880*2e192b24SSimon Glass * and the size of the region are 881*2e192b24SSimon Glass * selected by the caller. 882*2e192b24SSimon Glass * 883*2e192b24SSimon Glass * Returns: 0 if the test succeeds, 1 if the test fails. 884*2e192b24SSimon Glass */ 885*2e192b24SSimon Glass num_words++; 886*2e192b24SSimon Glass 887*2e192b24SSimon Glass /* 888*2e192b24SSimon Glass * Fill memory with a known pattern. 889*2e192b24SSimon Glass */ 890*2e192b24SSimon Glass for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { 891*2e192b24SSimon Glass WATCHDOG_RESET(); 892*2e192b24SSimon Glass addr[offset] = pattern; 893*2e192b24SSimon Glass } 894*2e192b24SSimon Glass 895*2e192b24SSimon Glass /* 896*2e192b24SSimon Glass * Check each location and invert it for the second pass. 897*2e192b24SSimon Glass */ 898*2e192b24SSimon Glass for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { 899*2e192b24SSimon Glass WATCHDOG_RESET(); 900*2e192b24SSimon Glass temp = addr[offset]; 901*2e192b24SSimon Glass if (temp != pattern) { 902*2e192b24SSimon Glass printf("\nFAILURE (read/write) @ 0x%.8lx:" 903*2e192b24SSimon Glass " expected 0x%.8lx, actual 0x%.8lx)\n", 904*2e192b24SSimon Glass start_addr + offset*sizeof(vu_long), 905*2e192b24SSimon Glass pattern, temp); 906*2e192b24SSimon Glass errs++; 907*2e192b24SSimon Glass if (ctrlc()) 908*2e192b24SSimon Glass return -1; 909*2e192b24SSimon Glass } 910*2e192b24SSimon Glass 911*2e192b24SSimon Glass anti_pattern = ~pattern; 912*2e192b24SSimon Glass addr[offset] = anti_pattern; 913*2e192b24SSimon Glass } 914*2e192b24SSimon Glass 915*2e192b24SSimon Glass /* 916*2e192b24SSimon Glass * Check each location for the inverted pattern and zero it. 917*2e192b24SSimon Glass */ 918*2e192b24SSimon Glass for (pattern = 1, offset = 0; offset < num_words; pattern++, offset++) { 919*2e192b24SSimon Glass WATCHDOG_RESET(); 920*2e192b24SSimon Glass anti_pattern = ~pattern; 921*2e192b24SSimon Glass temp = addr[offset]; 922*2e192b24SSimon Glass if (temp != anti_pattern) { 923*2e192b24SSimon Glass printf("\nFAILURE (read/write): @ 0x%.8lx:" 924*2e192b24SSimon Glass " expected 0x%.8lx, actual 0x%.8lx)\n", 925*2e192b24SSimon Glass start_addr + offset*sizeof(vu_long), 926*2e192b24SSimon Glass anti_pattern, temp); 927*2e192b24SSimon Glass errs++; 928*2e192b24SSimon Glass if (ctrlc()) 929*2e192b24SSimon Glass return -1; 930*2e192b24SSimon Glass } 931*2e192b24SSimon Glass addr[offset] = 0; 932*2e192b24SSimon Glass } 933*2e192b24SSimon Glass 934*2e192b24SSimon Glass return errs; 935*2e192b24SSimon Glass } 936*2e192b24SSimon Glass 937*2e192b24SSimon Glass static ulong mem_test_quick(vu_long *buf, ulong start_addr, ulong end_addr, 938*2e192b24SSimon Glass vu_long pattern, int iteration) 939*2e192b24SSimon Glass { 940*2e192b24SSimon Glass vu_long *end; 941*2e192b24SSimon Glass vu_long *addr; 942*2e192b24SSimon Glass ulong errs = 0; 943*2e192b24SSimon Glass ulong incr, length; 944*2e192b24SSimon Glass ulong val, readback; 945*2e192b24SSimon Glass 946*2e192b24SSimon Glass /* Alternate the pattern */ 947*2e192b24SSimon Glass incr = 1; 948*2e192b24SSimon Glass if (iteration & 1) { 949*2e192b24SSimon Glass incr = -incr; 950*2e192b24SSimon Glass /* 951*2e192b24SSimon Glass * Flip the pattern each time to make lots of zeros and 952*2e192b24SSimon Glass * then, the next time, lots of ones. We decrement 953*2e192b24SSimon Glass * the "negative" patterns and increment the "positive" 954*2e192b24SSimon Glass * patterns to preserve this feature. 955*2e192b24SSimon Glass */ 956*2e192b24SSimon Glass if (pattern & 0x80000000) 957*2e192b24SSimon Glass pattern = -pattern; /* complement & increment */ 958*2e192b24SSimon Glass else 959*2e192b24SSimon Glass pattern = ~pattern; 960*2e192b24SSimon Glass } 961*2e192b24SSimon Glass length = (end_addr - start_addr) / sizeof(ulong); 962*2e192b24SSimon Glass end = buf + length; 963*2e192b24SSimon Glass printf("\rPattern %08lX Writing..." 964*2e192b24SSimon Glass "%12s" 965*2e192b24SSimon Glass "\b\b\b\b\b\b\b\b\b\b", 966*2e192b24SSimon Glass pattern, ""); 967*2e192b24SSimon Glass 968*2e192b24SSimon Glass for (addr = buf, val = pattern; addr < end; addr++) { 969*2e192b24SSimon Glass WATCHDOG_RESET(); 970*2e192b24SSimon Glass *addr = val; 971*2e192b24SSimon Glass val += incr; 972*2e192b24SSimon Glass } 973*2e192b24SSimon Glass 974*2e192b24SSimon Glass puts("Reading..."); 975*2e192b24SSimon Glass 976*2e192b24SSimon Glass for (addr = buf, val = pattern; addr < end; addr++) { 977*2e192b24SSimon Glass WATCHDOG_RESET(); 978*2e192b24SSimon Glass readback = *addr; 979*2e192b24SSimon Glass if (readback != val) { 980*2e192b24SSimon Glass ulong offset = addr - buf; 981*2e192b24SSimon Glass 982*2e192b24SSimon Glass printf("\nMem error @ 0x%08X: " 983*2e192b24SSimon Glass "found %08lX, expected %08lX\n", 984*2e192b24SSimon Glass (uint)(uintptr_t)(start_addr + offset*sizeof(vu_long)), 985*2e192b24SSimon Glass readback, val); 986*2e192b24SSimon Glass errs++; 987*2e192b24SSimon Glass if (ctrlc()) 988*2e192b24SSimon Glass return -1; 989*2e192b24SSimon Glass } 990*2e192b24SSimon Glass val += incr; 991*2e192b24SSimon Glass } 992*2e192b24SSimon Glass 993*2e192b24SSimon Glass return errs; 994*2e192b24SSimon Glass } 995*2e192b24SSimon Glass 996*2e192b24SSimon Glass /* 997*2e192b24SSimon Glass * Perform a memory test. A more complete alternative test can be 998*2e192b24SSimon Glass * configured using CONFIG_SYS_ALT_MEMTEST. The complete test loops until 999*2e192b24SSimon Glass * interrupted by ctrl-c or by a failure of one of the sub-tests. 1000*2e192b24SSimon Glass */ 1001*2e192b24SSimon Glass static int do_mem_mtest(cmd_tbl_t *cmdtp, int flag, int argc, 1002*2e192b24SSimon Glass char * const argv[]) 1003*2e192b24SSimon Glass { 1004*2e192b24SSimon Glass ulong start, end; 1005*2e192b24SSimon Glass vu_long *buf, *dummy; 1006*2e192b24SSimon Glass ulong iteration_limit = 0; 1007*2e192b24SSimon Glass int ret; 1008*2e192b24SSimon Glass ulong errs = 0; /* number of errors, or -1 if interrupted */ 1009*2e192b24SSimon Glass ulong pattern = 0; 1010*2e192b24SSimon Glass int iteration; 1011*2e192b24SSimon Glass #if defined(CONFIG_SYS_ALT_MEMTEST) 1012*2e192b24SSimon Glass const int alt_test = 1; 1013*2e192b24SSimon Glass #else 1014*2e192b24SSimon Glass const int alt_test = 0; 1015*2e192b24SSimon Glass #endif 1016*2e192b24SSimon Glass 1017*2e192b24SSimon Glass start = CONFIG_SYS_MEMTEST_START; 1018*2e192b24SSimon Glass end = CONFIG_SYS_MEMTEST_END; 1019*2e192b24SSimon Glass 1020*2e192b24SSimon Glass if (argc > 1) 1021*2e192b24SSimon Glass if (strict_strtoul(argv[1], 16, &start) < 0) 1022*2e192b24SSimon Glass return CMD_RET_USAGE; 1023*2e192b24SSimon Glass 1024*2e192b24SSimon Glass if (argc > 2) 1025*2e192b24SSimon Glass if (strict_strtoul(argv[2], 16, &end) < 0) 1026*2e192b24SSimon Glass return CMD_RET_USAGE; 1027*2e192b24SSimon Glass 1028*2e192b24SSimon Glass if (argc > 3) 1029*2e192b24SSimon Glass if (strict_strtoul(argv[3], 16, &pattern) < 0) 1030*2e192b24SSimon Glass return CMD_RET_USAGE; 1031*2e192b24SSimon Glass 1032*2e192b24SSimon Glass if (argc > 4) 1033*2e192b24SSimon Glass if (strict_strtoul(argv[4], 16, &iteration_limit) < 0) 1034*2e192b24SSimon Glass return CMD_RET_USAGE; 1035*2e192b24SSimon Glass 1036*2e192b24SSimon Glass if (end < start) { 1037*2e192b24SSimon Glass printf("Refusing to do empty test\n"); 1038*2e192b24SSimon Glass return -1; 1039*2e192b24SSimon Glass } 1040*2e192b24SSimon Glass 1041*2e192b24SSimon Glass printf("Testing %08x ... %08x:\n", (uint)start, (uint)end); 1042*2e192b24SSimon Glass debug("%s:%d: start %#08lx end %#08lx\n", __func__, __LINE__, 1043*2e192b24SSimon Glass start, end); 1044*2e192b24SSimon Glass 1045*2e192b24SSimon Glass buf = map_sysmem(start, end - start); 1046*2e192b24SSimon Glass dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long)); 1047*2e192b24SSimon Glass for (iteration = 0; 1048*2e192b24SSimon Glass !iteration_limit || iteration < iteration_limit; 1049*2e192b24SSimon Glass iteration++) { 1050*2e192b24SSimon Glass if (ctrlc()) { 1051*2e192b24SSimon Glass errs = -1UL; 1052*2e192b24SSimon Glass break; 1053*2e192b24SSimon Glass } 1054*2e192b24SSimon Glass 1055*2e192b24SSimon Glass printf("Iteration: %6d\r", iteration + 1); 1056*2e192b24SSimon Glass debug("\n"); 1057*2e192b24SSimon Glass if (alt_test) { 1058*2e192b24SSimon Glass errs = mem_test_alt(buf, start, end, dummy); 1059*2e192b24SSimon Glass } else { 1060*2e192b24SSimon Glass errs = mem_test_quick(buf, start, end, pattern, 1061*2e192b24SSimon Glass iteration); 1062*2e192b24SSimon Glass } 1063*2e192b24SSimon Glass if (errs == -1UL) 1064*2e192b24SSimon Glass break; 1065*2e192b24SSimon Glass } 1066*2e192b24SSimon Glass 1067*2e192b24SSimon Glass /* 1068*2e192b24SSimon Glass * Work-around for eldk-4.2 which gives this warning if we try to 1069*2e192b24SSimon Glass * case in the unmap_sysmem() call: 1070*2e192b24SSimon Glass * warning: initialization discards qualifiers from pointer target type 1071*2e192b24SSimon Glass */ 1072*2e192b24SSimon Glass { 1073*2e192b24SSimon Glass void *vbuf = (void *)buf; 1074*2e192b24SSimon Glass void *vdummy = (void *)dummy; 1075*2e192b24SSimon Glass 1076*2e192b24SSimon Glass unmap_sysmem(vbuf); 1077*2e192b24SSimon Glass unmap_sysmem(vdummy); 1078*2e192b24SSimon Glass } 1079*2e192b24SSimon Glass 1080*2e192b24SSimon Glass if (errs == -1UL) { 1081*2e192b24SSimon Glass /* Memory test was aborted - write a newline to finish off */ 1082*2e192b24SSimon Glass putc('\n'); 1083*2e192b24SSimon Glass ret = 1; 1084*2e192b24SSimon Glass } else { 1085*2e192b24SSimon Glass printf("Tested %d iteration(s) with %lu errors.\n", 1086*2e192b24SSimon Glass iteration, errs); 1087*2e192b24SSimon Glass ret = errs != 0; 1088*2e192b24SSimon Glass } 1089*2e192b24SSimon Glass 1090*2e192b24SSimon Glass return ret; 1091*2e192b24SSimon Glass } 1092*2e192b24SSimon Glass #endif /* CONFIG_CMD_MEMTEST */ 1093*2e192b24SSimon Glass 1094*2e192b24SSimon Glass /* Modify memory. 1095*2e192b24SSimon Glass * 1096*2e192b24SSimon Glass * Syntax: 1097*2e192b24SSimon Glass * mm{.b, .w, .l, .q} {addr} 1098*2e192b24SSimon Glass * nm{.b, .w, .l, .q} {addr} 1099*2e192b24SSimon Glass */ 1100*2e192b24SSimon Glass static int 1101*2e192b24SSimon Glass mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) 1102*2e192b24SSimon Glass { 1103*2e192b24SSimon Glass ulong addr; 1104*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1105*2e192b24SSimon Glass u64 i; 1106*2e192b24SSimon Glass #else 1107*2e192b24SSimon Glass ulong i; 1108*2e192b24SSimon Glass #endif 1109*2e192b24SSimon Glass int nbytes, size; 1110*2e192b24SSimon Glass void *ptr = NULL; 1111*2e192b24SSimon Glass 1112*2e192b24SSimon Glass if (argc != 2) 1113*2e192b24SSimon Glass return CMD_RET_USAGE; 1114*2e192b24SSimon Glass 1115*2e192b24SSimon Glass bootretry_reset_cmd_timeout(); /* got a good command to get here */ 1116*2e192b24SSimon Glass /* We use the last specified parameters, unless new ones are 1117*2e192b24SSimon Glass * entered. 1118*2e192b24SSimon Glass */ 1119*2e192b24SSimon Glass addr = mm_last_addr; 1120*2e192b24SSimon Glass size = mm_last_size; 1121*2e192b24SSimon Glass 1122*2e192b24SSimon Glass if ((flag & CMD_FLAG_REPEAT) == 0) { 1123*2e192b24SSimon Glass /* New command specified. Check for a size specification. 1124*2e192b24SSimon Glass * Defaults to long if no or incorrect specification. 1125*2e192b24SSimon Glass */ 1126*2e192b24SSimon Glass if ((size = cmd_get_data_size(argv[0], 4)) < 0) 1127*2e192b24SSimon Glass return 1; 1128*2e192b24SSimon Glass 1129*2e192b24SSimon Glass /* Address is specified since argc > 1 1130*2e192b24SSimon Glass */ 1131*2e192b24SSimon Glass addr = simple_strtoul(argv[1], NULL, 16); 1132*2e192b24SSimon Glass addr += base_address; 1133*2e192b24SSimon Glass } 1134*2e192b24SSimon Glass 1135*2e192b24SSimon Glass #ifdef CONFIG_HAS_DATAFLASH 1136*2e192b24SSimon Glass if (addr_dataflash(addr)){ 1137*2e192b24SSimon Glass puts ("Can't modify DataFlash in place. Use cp instead.\n\r"); 1138*2e192b24SSimon Glass return 0; 1139*2e192b24SSimon Glass } 1140*2e192b24SSimon Glass #endif 1141*2e192b24SSimon Glass 1142*2e192b24SSimon Glass #ifdef CONFIG_BLACKFIN 1143*2e192b24SSimon Glass if (addr_bfin_on_chip_mem(addr)) { 1144*2e192b24SSimon Glass puts ("Can't modify L1 instruction in place. Use cp instead.\n\r"); 1145*2e192b24SSimon Glass return 0; 1146*2e192b24SSimon Glass } 1147*2e192b24SSimon Glass #endif 1148*2e192b24SSimon Glass 1149*2e192b24SSimon Glass /* Print the address, followed by value. Then accept input for 1150*2e192b24SSimon Glass * the next value. A non-converted value exits. 1151*2e192b24SSimon Glass */ 1152*2e192b24SSimon Glass do { 1153*2e192b24SSimon Glass ptr = map_sysmem(addr, size); 1154*2e192b24SSimon Glass printf("%08lx:", addr); 1155*2e192b24SSimon Glass if (size == 4) 1156*2e192b24SSimon Glass printf(" %08x", *((u32 *)ptr)); 1157*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1158*2e192b24SSimon Glass else if (size == 8) 1159*2e192b24SSimon Glass printf(" %016" PRIx64, *((u64 *)ptr)); 1160*2e192b24SSimon Glass #endif 1161*2e192b24SSimon Glass else if (size == 2) 1162*2e192b24SSimon Glass printf(" %04x", *((u16 *)ptr)); 1163*2e192b24SSimon Glass else 1164*2e192b24SSimon Glass printf(" %02x", *((u8 *)ptr)); 1165*2e192b24SSimon Glass 1166*2e192b24SSimon Glass nbytes = cli_readline(" ? "); 1167*2e192b24SSimon Glass if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) { 1168*2e192b24SSimon Glass /* <CR> pressed as only input, don't modify current 1169*2e192b24SSimon Glass * location and move to next. "-" pressed will go back. 1170*2e192b24SSimon Glass */ 1171*2e192b24SSimon Glass if (incrflag) 1172*2e192b24SSimon Glass addr += nbytes ? -size : size; 1173*2e192b24SSimon Glass nbytes = 1; 1174*2e192b24SSimon Glass /* good enough to not time out */ 1175*2e192b24SSimon Glass bootretry_reset_cmd_timeout(); 1176*2e192b24SSimon Glass } 1177*2e192b24SSimon Glass #ifdef CONFIG_BOOT_RETRY_TIME 1178*2e192b24SSimon Glass else if (nbytes == -2) { 1179*2e192b24SSimon Glass break; /* timed out, exit the command */ 1180*2e192b24SSimon Glass } 1181*2e192b24SSimon Glass #endif 1182*2e192b24SSimon Glass else { 1183*2e192b24SSimon Glass char *endp; 1184*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1185*2e192b24SSimon Glass i = simple_strtoull(console_buffer, &endp, 16); 1186*2e192b24SSimon Glass #else 1187*2e192b24SSimon Glass i = simple_strtoul(console_buffer, &endp, 16); 1188*2e192b24SSimon Glass #endif 1189*2e192b24SSimon Glass nbytes = endp - console_buffer; 1190*2e192b24SSimon Glass if (nbytes) { 1191*2e192b24SSimon Glass /* good enough to not time out 1192*2e192b24SSimon Glass */ 1193*2e192b24SSimon Glass bootretry_reset_cmd_timeout(); 1194*2e192b24SSimon Glass if (size == 4) 1195*2e192b24SSimon Glass *((u32 *)ptr) = i; 1196*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1197*2e192b24SSimon Glass else if (size == 8) 1198*2e192b24SSimon Glass *((u64 *)ptr) = i; 1199*2e192b24SSimon Glass #endif 1200*2e192b24SSimon Glass else if (size == 2) 1201*2e192b24SSimon Glass *((u16 *)ptr) = i; 1202*2e192b24SSimon Glass else 1203*2e192b24SSimon Glass *((u8 *)ptr) = i; 1204*2e192b24SSimon Glass if (incrflag) 1205*2e192b24SSimon Glass addr += size; 1206*2e192b24SSimon Glass } 1207*2e192b24SSimon Glass } 1208*2e192b24SSimon Glass } while (nbytes); 1209*2e192b24SSimon Glass if (ptr) 1210*2e192b24SSimon Glass unmap_sysmem(ptr); 1211*2e192b24SSimon Glass 1212*2e192b24SSimon Glass mm_last_addr = addr; 1213*2e192b24SSimon Glass mm_last_size = size; 1214*2e192b24SSimon Glass return 0; 1215*2e192b24SSimon Glass } 1216*2e192b24SSimon Glass 1217*2e192b24SSimon Glass #ifdef CONFIG_CMD_CRC32 1218*2e192b24SSimon Glass 1219*2e192b24SSimon Glass static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1220*2e192b24SSimon Glass { 1221*2e192b24SSimon Glass int flags = 0; 1222*2e192b24SSimon Glass int ac; 1223*2e192b24SSimon Glass char * const *av; 1224*2e192b24SSimon Glass 1225*2e192b24SSimon Glass if (argc < 3) 1226*2e192b24SSimon Glass return CMD_RET_USAGE; 1227*2e192b24SSimon Glass 1228*2e192b24SSimon Glass av = argv + 1; 1229*2e192b24SSimon Glass ac = argc - 1; 1230*2e192b24SSimon Glass #ifdef CONFIG_HASH_VERIFY 1231*2e192b24SSimon Glass if (strcmp(*av, "-v") == 0) { 1232*2e192b24SSimon Glass flags |= HASH_FLAG_VERIFY | HASH_FLAG_ENV; 1233*2e192b24SSimon Glass av++; 1234*2e192b24SSimon Glass ac--; 1235*2e192b24SSimon Glass } 1236*2e192b24SSimon Glass #endif 1237*2e192b24SSimon Glass 1238*2e192b24SSimon Glass return hash_command("crc32", flags, cmdtp, flag, ac, av); 1239*2e192b24SSimon Glass } 1240*2e192b24SSimon Glass 1241*2e192b24SSimon Glass #endif 1242*2e192b24SSimon Glass 1243*2e192b24SSimon Glass /**************************************************/ 1244*2e192b24SSimon Glass U_BOOT_CMD( 1245*2e192b24SSimon Glass md, 3, 1, do_mem_md, 1246*2e192b24SSimon Glass "memory display", 1247*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1248*2e192b24SSimon Glass "[.b, .w, .l, .q] address [# of objects]" 1249*2e192b24SSimon Glass #else 1250*2e192b24SSimon Glass "[.b, .w, .l] address [# of objects]" 1251*2e192b24SSimon Glass #endif 1252*2e192b24SSimon Glass ); 1253*2e192b24SSimon Glass 1254*2e192b24SSimon Glass 1255*2e192b24SSimon Glass U_BOOT_CMD( 1256*2e192b24SSimon Glass mm, 2, 1, do_mem_mm, 1257*2e192b24SSimon Glass "memory modify (auto-incrementing address)", 1258*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1259*2e192b24SSimon Glass "[.b, .w, .l, .q] address" 1260*2e192b24SSimon Glass #else 1261*2e192b24SSimon Glass "[.b, .w, .l] address" 1262*2e192b24SSimon Glass #endif 1263*2e192b24SSimon Glass ); 1264*2e192b24SSimon Glass 1265*2e192b24SSimon Glass 1266*2e192b24SSimon Glass U_BOOT_CMD( 1267*2e192b24SSimon Glass nm, 2, 1, do_mem_nm, 1268*2e192b24SSimon Glass "memory modify (constant address)", 1269*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1270*2e192b24SSimon Glass "[.b, .w, .l, .q] address" 1271*2e192b24SSimon Glass #else 1272*2e192b24SSimon Glass "[.b, .w, .l] address" 1273*2e192b24SSimon Glass #endif 1274*2e192b24SSimon Glass ); 1275*2e192b24SSimon Glass 1276*2e192b24SSimon Glass U_BOOT_CMD( 1277*2e192b24SSimon Glass mw, 4, 1, do_mem_mw, 1278*2e192b24SSimon Glass "memory write (fill)", 1279*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1280*2e192b24SSimon Glass "[.b, .w, .l, .q] address value [count]" 1281*2e192b24SSimon Glass #else 1282*2e192b24SSimon Glass "[.b, .w, .l] address value [count]" 1283*2e192b24SSimon Glass #endif 1284*2e192b24SSimon Glass ); 1285*2e192b24SSimon Glass 1286*2e192b24SSimon Glass U_BOOT_CMD( 1287*2e192b24SSimon Glass cp, 4, 1, do_mem_cp, 1288*2e192b24SSimon Glass "memory copy", 1289*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1290*2e192b24SSimon Glass "[.b, .w, .l, .q] source target count" 1291*2e192b24SSimon Glass #else 1292*2e192b24SSimon Glass "[.b, .w, .l] source target count" 1293*2e192b24SSimon Glass #endif 1294*2e192b24SSimon Glass ); 1295*2e192b24SSimon Glass 1296*2e192b24SSimon Glass U_BOOT_CMD( 1297*2e192b24SSimon Glass cmp, 4, 1, do_mem_cmp, 1298*2e192b24SSimon Glass "memory compare", 1299*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1300*2e192b24SSimon Glass "[.b, .w, .l, .q] addr1 addr2 count" 1301*2e192b24SSimon Glass #else 1302*2e192b24SSimon Glass "[.b, .w, .l] addr1 addr2 count" 1303*2e192b24SSimon Glass #endif 1304*2e192b24SSimon Glass ); 1305*2e192b24SSimon Glass 1306*2e192b24SSimon Glass #ifdef CONFIG_CMD_CRC32 1307*2e192b24SSimon Glass 1308*2e192b24SSimon Glass #ifndef CONFIG_HASH_VERIFY 1309*2e192b24SSimon Glass 1310*2e192b24SSimon Glass U_BOOT_CMD( 1311*2e192b24SSimon Glass crc32, 4, 1, do_mem_crc, 1312*2e192b24SSimon Glass "checksum calculation", 1313*2e192b24SSimon Glass "address count [addr]\n - compute CRC32 checksum [save at addr]" 1314*2e192b24SSimon Glass ); 1315*2e192b24SSimon Glass 1316*2e192b24SSimon Glass #else /* CONFIG_HASH_VERIFY */ 1317*2e192b24SSimon Glass 1318*2e192b24SSimon Glass U_BOOT_CMD( 1319*2e192b24SSimon Glass crc32, 5, 1, do_mem_crc, 1320*2e192b24SSimon Glass "checksum calculation", 1321*2e192b24SSimon Glass "address count [addr]\n - compute CRC32 checksum [save at addr]\n" 1322*2e192b24SSimon Glass "-v address count crc\n - verify crc of memory area" 1323*2e192b24SSimon Glass ); 1324*2e192b24SSimon Glass 1325*2e192b24SSimon Glass #endif /* CONFIG_HASH_VERIFY */ 1326*2e192b24SSimon Glass 1327*2e192b24SSimon Glass #endif 1328*2e192b24SSimon Glass 1329*2e192b24SSimon Glass #ifdef CONFIG_CMD_MEMINFO 1330*2e192b24SSimon Glass __weak void board_show_dram(phys_size_t size) 1331*2e192b24SSimon Glass { 1332*2e192b24SSimon Glass puts("DRAM: "); 1333*2e192b24SSimon Glass print_size(size, "\n"); 1334*2e192b24SSimon Glass } 1335*2e192b24SSimon Glass 1336*2e192b24SSimon Glass static int do_mem_info(cmd_tbl_t *cmdtp, int flag, int argc, 1337*2e192b24SSimon Glass char * const argv[]) 1338*2e192b24SSimon Glass { 1339*2e192b24SSimon Glass board_show_dram(gd->ram_size); 1340*2e192b24SSimon Glass 1341*2e192b24SSimon Glass return 0; 1342*2e192b24SSimon Glass } 1343*2e192b24SSimon Glass #endif 1344*2e192b24SSimon Glass 1345*2e192b24SSimon Glass U_BOOT_CMD( 1346*2e192b24SSimon Glass base, 2, 1, do_mem_base, 1347*2e192b24SSimon Glass "print or set address offset", 1348*2e192b24SSimon Glass "\n - print address offset for memory commands\n" 1349*2e192b24SSimon Glass "base off\n - set address offset for memory commands to 'off'" 1350*2e192b24SSimon Glass ); 1351*2e192b24SSimon Glass 1352*2e192b24SSimon Glass U_BOOT_CMD( 1353*2e192b24SSimon Glass loop, 3, 1, do_mem_loop, 1354*2e192b24SSimon Glass "infinite loop on address range", 1355*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1356*2e192b24SSimon Glass "[.b, .w, .l, .q] address number_of_objects" 1357*2e192b24SSimon Glass #else 1358*2e192b24SSimon Glass "[.b, .w, .l] address number_of_objects" 1359*2e192b24SSimon Glass #endif 1360*2e192b24SSimon Glass ); 1361*2e192b24SSimon Glass 1362*2e192b24SSimon Glass #ifdef CONFIG_LOOPW 1363*2e192b24SSimon Glass U_BOOT_CMD( 1364*2e192b24SSimon Glass loopw, 4, 1, do_mem_loopw, 1365*2e192b24SSimon Glass "infinite write loop on address range", 1366*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1367*2e192b24SSimon Glass "[.b, .w, .l, .q] address number_of_objects data_to_write" 1368*2e192b24SSimon Glass #else 1369*2e192b24SSimon Glass "[.b, .w, .l] address number_of_objects data_to_write" 1370*2e192b24SSimon Glass #endif 1371*2e192b24SSimon Glass ); 1372*2e192b24SSimon Glass #endif /* CONFIG_LOOPW */ 1373*2e192b24SSimon Glass 1374*2e192b24SSimon Glass #ifdef CONFIG_CMD_MEMTEST 1375*2e192b24SSimon Glass U_BOOT_CMD( 1376*2e192b24SSimon Glass mtest, 5, 1, do_mem_mtest, 1377*2e192b24SSimon Glass "simple RAM read/write test", 1378*2e192b24SSimon Glass "[start [end [pattern [iterations]]]]" 1379*2e192b24SSimon Glass ); 1380*2e192b24SSimon Glass #endif /* CONFIG_CMD_MEMTEST */ 1381*2e192b24SSimon Glass 1382*2e192b24SSimon Glass #ifdef CONFIG_MX_CYCLIC 1383*2e192b24SSimon Glass U_BOOT_CMD( 1384*2e192b24SSimon Glass mdc, 4, 1, do_mem_mdc, 1385*2e192b24SSimon Glass "memory display cyclic", 1386*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1387*2e192b24SSimon Glass "[.b, .w, .l, .q] address count delay(ms)" 1388*2e192b24SSimon Glass #else 1389*2e192b24SSimon Glass "[.b, .w, .l] address count delay(ms)" 1390*2e192b24SSimon Glass #endif 1391*2e192b24SSimon Glass ); 1392*2e192b24SSimon Glass 1393*2e192b24SSimon Glass U_BOOT_CMD( 1394*2e192b24SSimon Glass mwc, 4, 1, do_mem_mwc, 1395*2e192b24SSimon Glass "memory write cyclic", 1396*2e192b24SSimon Glass #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA 1397*2e192b24SSimon Glass "[.b, .w, .l, .q] address value delay(ms)" 1398*2e192b24SSimon Glass #else 1399*2e192b24SSimon Glass "[.b, .w, .l] address value delay(ms)" 1400*2e192b24SSimon Glass #endif 1401*2e192b24SSimon Glass ); 1402*2e192b24SSimon Glass #endif /* CONFIG_MX_CYCLIC */ 1403*2e192b24SSimon Glass 1404*2e192b24SSimon Glass #ifdef CONFIG_CMD_MEMINFO 1405*2e192b24SSimon Glass U_BOOT_CMD( 1406*2e192b24SSimon Glass meminfo, 3, 1, do_mem_info, 1407*2e192b24SSimon Glass "display memory information", 1408*2e192b24SSimon Glass "" 1409*2e192b24SSimon Glass ); 1410*2e192b24SSimon Glass #endif 1411