Skip to content
Snippets Groups Projects
cmd_mem.c 29.9 KiB
Newer Older
  • Learn to ignore specific revisions
  • Simon Glass's avatar
    Simon Glass committed
    	ulong start, end;
    
    	vu_long *buf, *dummy;
    
    	ulong iteration_limit = 0;
    
    	ulong errs = 0;	/* number of errors, or -1 if interrupted */
    
    	ulong pattern = 0;
    
    	int iteration;
    
    #if defined(CONFIG_SYS_ALT_MEMTEST)
    	const int alt_test = 1;
    #else
    	const int alt_test = 0;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    #endif
    
    	start = CONFIG_SYS_MEMTEST_START;
    	end = CONFIG_SYS_MEMTEST_END;
    
    
    		if (strict_strtoul(argv[1], 16, &start) < 0)
    			return CMD_RET_USAGE;
    
    		if (strict_strtoul(argv[2], 16, &end) < 0)
    			return CMD_RET_USAGE;
    
    		if (strict_strtoul(argv[3], 16, &pattern) < 0)
    			return CMD_RET_USAGE;
    
    		if (strict_strtoul(argv[4], 16, &iteration_limit) < 0)
    			return CMD_RET_USAGE;
    
    	if (end < start) {
    		printf("Refusing to do empty test\n");
    		return -1;
    	}
    
    Simon Glass's avatar
    Simon Glass committed
    	printf("Testing %08x ... %08x:\n", (uint)start, (uint)end);
    	debug("%s:%d: start %#08lx end %#08lx\n", __func__, __LINE__,
    	      start, end);
    
    	buf = map_sysmem(start, end - start);
    	dummy = map_sysmem(CONFIG_SYS_MEMTEST_SCRATCH, sizeof(vu_long));
    
    	for (iteration = 0;
    			!iteration_limit || iteration < iteration_limit;
    			iteration++) {
    		if (ctrlc()) {
    			errs = -1UL;
    			break;
    		}
    
    		printf("Iteration: %6d\r", iteration + 1);
    		debug("\n");
    
    		if (alt_test) {
    			errs = mem_test_alt(buf, start, end, dummy);
    		} else {
    			errs = mem_test_quick(buf, start, end, pattern,
    					      iteration);
    		}
    		if (errs == -1UL)
    			break;
    	}
    
    	/*
    	 * Work-around for eldk-4.2 which gives this warning if we try to
    	 * case in the unmap_sysmem() call:
    	 * warning: initialization discards qualifiers from pointer target type
    	 */
    	{
    		void *vbuf = (void *)buf;
    		void *vdummy = (void *)dummy;
    
    		unmap_sysmem(vbuf);
    		unmap_sysmem(vdummy);
    
    	}
    
    	if (errs == -1UL) {
    
    		/* Memory test was aborted - write a newline to finish off */
    		putc('\n');
    
    		ret = 1;
    	} else {
    		printf("Tested %d iteration(s) with %lu errors.\n",
    			iteration, errs);
    		ret = errs != 0;
    	}
    
    	return ret;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    }
    
    #endif	/* CONFIG_CMD_MEMTEST */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    /* Modify memory.
     *
     * Syntax:
    
     *	mm{.b, .w, .l, .q} {addr}
     *	nm{.b, .w, .l, .q} {addr}
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
     */
    static int
    
    mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[])
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    {
    
    	ulong	addr;
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	u64 i;
    #else
    	ulong i;
    #endif
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	bootretry_reset_cmd_timeout();	/* got a good command to get here */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	/* We use the last specified parameters, unless new ones are
    	 * entered.
    	 */
    	addr = mm_last_addr;
    	size = mm_last_size;
    
    	if ((flag & CMD_FLAG_REPEAT) == 0) {
    		/* New command specified.  Check for a size specification.
    		 * Defaults to long if no or incorrect specification.
    		 */
    
    		if ((size = cmd_get_data_size(argv[0], 4)) < 0)
    			return 1;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    		/* Address is specified since argc > 1
    		*/
    		addr = simple_strtoul(argv[1], NULL, 16);
    		addr += base_address;
    	}
    
    
    #ifdef CONFIG_HAS_DATAFLASH
    	if (addr_dataflash(addr)){
    
    		puts ("Can't modify DataFlash in place. Use cp instead.\n\r");
    
    #ifdef CONFIG_BLACKFIN
    	if (addr_bfin_on_chip_mem(addr)) {
    		puts ("Can't modify L1 instruction in place. Use cp instead.\n\r");
    		return 0;
    	}
    #endif
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	/* Print the address, followed by value.  Then accept input for
    	 * the next value.  A non-converted value exits.
    	 */
    	do {
    
    		ptr = map_sysmem(addr, size);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		printf("%08lx:", addr);
    		if (size == 4)
    
    			printf(" %08x", *((u32 *)ptr));
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    		else if (size == 8)
    
    			printf(" %016" PRIx64, *((u64 *)ptr));
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		else if (size == 2)
    
    			printf(" %04x", *((u16 *)ptr));
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		else
    
    			printf(" %02x", *((u8 *)ptr));
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    		nbytes = cli_readline(" ? ");
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		if (nbytes == 0 || (nbytes == 1 && console_buffer[0] == '-')) {
    			/* <CR> pressed as only input, don't modify current
    			 * location and move to next. "-" pressed will go back.
    			 */
    			if (incrflag)
    				addr += nbytes ? -size : size;
    			nbytes = 1;
    
    			/* good enough to not time out */
    			bootretry_reset_cmd_timeout();
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    		}
    #ifdef CONFIG_BOOT_RETRY_TIME
    		else if (nbytes == -2) {
    			break;	/* timed out, exit the command	*/
    		}
    #endif
    		else {
    			char *endp;
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    			i = simple_strtoull(console_buffer, &endp, 16);
    #else
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    			i = simple_strtoul(console_buffer, &endp, 16);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    			nbytes = endp - console_buffer;
    			if (nbytes) {
    				/* good enough to not time out
    				 */
    
    				bootretry_reset_cmd_timeout();
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    				if (size == 4)
    
    					*((u32 *)ptr) = i;
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    				else if (size == 8)
    					*((u64 *)ptr) = i;
    #endif
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    				else if (size == 2)
    
    					*((u16 *)ptr) = i;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    				else
    
    					*((u8 *)ptr) = i;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    				if (incrflag)
    					addr += size;
    			}
    		}
    	} while (nbytes);
    
    	if (ptr)
    		unmap_sysmem(ptr);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	mm_last_addr = addr;
    	mm_last_size = size;
    	return 0;
    }
    
    
    #ifdef CONFIG_CMD_CRC32
    
    
    static int do_mem_crc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    {
    
    	int flags = 0;
    
    	if (argc < 3)
    
    
    	av = argv + 1;
    	ac = argc - 1;
    
    #ifdef CONFIG_HASH_VERIFY
    
    	if (strcmp(*av, "-v") == 0) {
    
    		flags |= HASH_FLAG_VERIFY;
    
    	return hash_command("crc32", flags, cmdtp, flag, ac, av);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    /**************************************************/
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	md,	3,	1,	do_mem_md,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"memory display",
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	"[.b, .w, .l, .q] address [# of objects]"
    #else
    
    	"[.b, .w, .l] address [# of objects]"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	mm,	2,	1,	do_mem_mm,
    
    	"memory modify (auto-incrementing address)",
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	"[.b, .w, .l, .q] address"
    #else
    
    	"[.b, .w, .l] address"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	nm,	2,	1,	do_mem_nm,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"memory modify (constant address)",
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	"[.b, .w, .l, .q] address"
    #else
    
    	"[.b, .w, .l] address"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    );
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	mw,	4,	1,	do_mem_mw,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"memory write (fill)",
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	"[.b, .w, .l, .q] address value [count]"
    #else
    
    	"[.b, .w, .l] address value [count]"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    );
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	cp,	4,	1,	do_mem_cp,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"memory copy",
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	"[.b, .w, .l, .q] source target count"
    #else
    
    	"[.b, .w, .l] source target count"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    );
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	cmp,	4,	1,	do_mem_cmp,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"memory compare",
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	"[.b, .w, .l, .q] addr1 addr2 count"
    #else
    
    	"[.b, .w, .l] addr1 addr2 count"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    );
    
    
    #ifdef CONFIG_CMD_CRC32
    
    
    #ifndef CONFIG_CRC32_VERIFY
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	crc32,	4,	1,	do_mem_crc,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"checksum calculation",
    
    	"address count [addr]\n    - compute CRC32 checksum [save at addr]"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    );
    
    
    #else	/* CONFIG_CRC32_VERIFY */
    
    U_BOOT_CMD(
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	crc32,	5,	1,	do_mem_crc,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"checksum calculation",
    
    	"address count [addr]\n    - compute CRC32 checksum [save at addr]\n"
    
    	"-v address count crc\n    - verify crc of memory area"
    
    );
    
    #endif	/* CONFIG_CRC32_VERIFY */
    
    
    #ifdef CONFIG_CMD_MEMINFO
    __weak void board_show_dram(ulong size)
    {
    	puts("DRAM:  ");
    	print_size(size, "\n");
    }
    
    static int do_mem_info(cmd_tbl_t *cmdtp, int flag, int argc,
    		       char * const argv[])
    {
    	board_show_dram(gd->ram_size);
    
    	return 0;
    }
    #endif
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	base,	2,	1,	do_mem_base,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"print or set address offset",
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"\n    - print address offset for memory commands\n"
    
    	"base off\n    - set address offset for memory commands to 'off'"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    );
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	loop,	3,	1,	do_mem_loop,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"infinite loop on address range",
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	"[.b, .w, .l, .q] address number_of_objects"
    #else
    
    	"[.b, .w, .l] address number_of_objects"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    );
    
    
    #ifdef CONFIG_LOOPW
    U_BOOT_CMD(
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	loopw,	4,	1,	do_mem_loopw,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"infinite write loop on address range",
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	"[.b, .w, .l, .q] address number_of_objects data_to_write"
    #else
    
    	"[.b, .w, .l] address number_of_objects data_to_write"
    
    );
    #endif /* CONFIG_LOOPW */
    
    
    #ifdef CONFIG_CMD_MEMTEST
    
    	mtest,	5,	1,	do_mem_mtest,
    
    	"simple RAM read/write test",
    	"[start [end [pattern [iterations]]]]"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    );
    
    #endif	/* CONFIG_CMD_MEMTEST */
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    #ifdef CONFIG_MX_CYCLIC
    U_BOOT_CMD(
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	mdc,	4,	1,	do_mem_mdc,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"memory display cyclic",
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	"[.b, .w, .l, .q] address count delay(ms)"
    #else
    
    	"[.b, .w, .l] address count delay(ms)"
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	mwc,	4,	1,	do_mem_mwc,
    
    Peter Tyser's avatar
    Peter Tyser committed
    	"memory write cyclic",
    
    #ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
    	"[.b, .w, .l, .q] address value delay(ms)"
    #else
    
    	"[.b, .w, .l] address value delay(ms)"
    
    );
    #endif /* CONFIG_MX_CYCLIC */
    
    
    #ifdef CONFIG_CMD_MEMINFO
    U_BOOT_CMD(
    	meminfo,	3,	1,	do_mem_info,
    	"display memory information",
    	""
    );
    #endif