Skip to content
Snippets Groups Projects
cmd_mem.c 28.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • Wolfgang Denk's avatar
    Wolfgang Denk committed
     *
     * Syntax:
     *	mm{.b, .w, .l} {addr}
     *	nm{.b, .w, .l} {addr}
     */
    static int
    mod_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char *argv[])
    {
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	extern char console_buffer[];
    
    	if (argc != 2) {
    		printf ("Usage:\n%s\n", cmdtp->usage);
    		return 1;
    	}
    
    #ifdef CONFIG_BOOT_RETRY_TIME
    	reset_cmd_timeout();	/* got a good command to get here */
    #endif
    	/* 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 {
    		printf("%08lx:", addr);
    		if (size == 4)
    			printf(" %08x", *((uint   *)addr));
    		else if (size == 2)
    			printf(" %04x", *((ushort *)addr));
    		else
    			printf(" %02x", *((u_char *)addr));
    
    		nbytes = readline (" ? ");
    		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;
    #ifdef CONFIG_BOOT_RETRY_TIME
    			reset_cmd_timeout(); /* good enough to not time out */
    #endif
    		}
    #ifdef CONFIG_BOOT_RETRY_TIME
    		else if (nbytes == -2) {
    			break;	/* timed out, exit the command	*/
    		}
    #endif
    		else {
    			char *endp;
    			i = simple_strtoul(console_buffer, &endp, 16);
    			nbytes = endp - console_buffer;
    			if (nbytes) {
    #ifdef CONFIG_BOOT_RETRY_TIME
    				/* good enough to not time out
    				 */
    				reset_cmd_timeout();
    #endif
    				if (size == 4)
    					*((uint   *)addr) = i;
    				else if (size == 2)
    					*((ushort *)addr) = i;
    				else
    					*((u_char *)addr) = i;
    				if (incrflag)
    					addr += size;
    			}
    		}
    	} while (nbytes);
    
    	mm_last_addr = addr;
    	mm_last_size = size;
    	return 0;
    }
    
    
    #ifndef CONFIG_CRC32_VERIFY
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
    {
    
    	ulong addr, length;
    	ulong crc;
    	ulong *ptr;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	if (argc < 3) {
    		printf ("Usage:\n%s\n", cmdtp->usage);
    		return 1;
    	}
    
    
    	addr = simple_strtoul (argv[1], NULL, 16);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	addr += base_address;
    
    
    	length = simple_strtoul (argv[2], NULL, 16);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	crc = crc32 (0, (const uchar *) addr, length);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    	printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
    
    			addr, addr + length - 1, crc);
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    
    
    	if (argc > 3) {
    		ptr = (ulong *) simple_strtoul (argv[3], NULL, 16);
    		*ptr = crc;
    	}
    
    #else	/* CONFIG_CRC32_VERIFY */
    
    int do_mem_crc (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
    {
    	ulong addr, length;
    	ulong crc;
    	ulong *ptr;
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	ulong vcrc;
    
    	int verify;
    	int ac;
    	char **av;
    
    	if (argc < 3) {
      usage:
    		printf ("Usage:\n%s\n", cmdtp->usage);
    		return 1;
    	}
    
    	av = argv + 1;
    	ac = argc - 1;
    	if (strcmp(*av, "-v") == 0) {
    		verify = 1;
    		av++;
    		ac--;
    		if (ac < 3)
    			goto usage;
    	} else
    		verify = 0;
    
    	addr = simple_strtoul(*av++, NULL, 16);
    	addr += base_address;
    	length = simple_strtoul(*av++, NULL, 16);
    
    	crc = crc32(0, (const uchar *) addr, length);
    
    	if (!verify) {
    		printf ("CRC32 for %08lx ... %08lx ==> %08lx\n",
    				addr, addr + length - 1, crc);
    		if (ac > 2) {
    			ptr = (ulong *) simple_strtoul (*av++, NULL, 16);
    			*ptr = crc;
    		}
    	} else {
    		vcrc = simple_strtoul(*av++, NULL, 16);
    		if (vcrc != crc) {
    			printf ("CRC32 for %08lx ... %08lx ==> %08lx != %08lx ** ERROR **\n",
    					addr, addr + length - 1, crc, vcrc);
    			return 1;
    		}
    	}
    
    	return 0;
    
    }
    #endif	/* CONFIG_CRC32_VERIFY */
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    /**************************************************/
    
    #if defined(CONFIG_CMD_MEMORY)
    
    U_BOOT_CMD(
    	md,     3,     1,      do_mem_md,
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"md      - memory display\n",
    	"[.b, .w, .l] address [# of objects]\n    - memory display\n"
    );
    
    
    
    U_BOOT_CMD(
    	mm,     2,      1,       do_mem_mm,
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"mm      - memory modify (auto-incrementing)\n",
    	"[.b, .w, .l] address\n" "    - memory modify, auto increment address\n"
    );
    
    
    
    U_BOOT_CMD(
    	nm,     2,	    1,     	do_mem_nm,
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"nm      - memory modify (constant address)\n",
    	"[.b, .w, .l] address\n    - memory modify, read and keep address\n"
    );
    
    
    U_BOOT_CMD(
    	mw,    4,    1,     do_mem_mw,
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"mw      - memory write (fill)\n",
    	"[.b, .w, .l] address value [count]\n    - write memory\n"
    );
    
    
    U_BOOT_CMD(
    	cp,    4,    1,    do_mem_cp,
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"cp      - memory copy\n",
    	"[.b, .w, .l] source target count\n    - copy memory\n"
    );
    
    
    U_BOOT_CMD(
    	cmp,    4,     1,     do_mem_cmp,
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"cmp     - memory compare\n",
    	"[.b, .w, .l] addr1 addr2 count\n    - compare memory\n"
    );
    
    
    #ifndef CONFIG_CRC32_VERIFY
    
    
    U_BOOT_CMD(
    	crc32,    4,    1,     do_mem_crc,
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"crc32   - checksum calculation\n",
    	"address count [addr]\n    - compute CRC32 checksum [save at addr]\n"
    );
    
    
    #else	/* CONFIG_CRC32_VERIFY */
    
    U_BOOT_CMD(
    	crc32,    5,    1,     do_mem_crc,
    	"crc32   - checksum calculation\n",
    	"address count [addr]\n    - compute CRC32 checksum [save at addr]\n"
    	"-v address count crc\n    - verify crc of memory area\n"
    );
    
    #endif	/* CONFIG_CRC32_VERIFY */
    
    
    U_BOOT_CMD(
    	base,    2,    1,     do_mem_base,
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"base    - print or set address offset\n",
    	"\n    - print address offset for memory commands\n"
    	"base off\n    - set address offset for memory commands to 'off'\n"
    );
    
    
    U_BOOT_CMD(
    	loop,    3,    1,    do_mem_loop,
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"loop    - infinite loop on address range\n",
    	"[.b, .w, .l] address number_of_objects\n"
    	"    - loop on a set of addresses\n"
    );
    
    
    #ifdef CONFIG_LOOPW
    U_BOOT_CMD(
    	loopw,    4,    1,    do_mem_loopw,
    	"loopw   - infinite write loop on address range\n",
    	"[.b, .w, .l] address number_of_objects data_to_write\n"
    	"    - loop on a set of addresses\n"
    );
    #endif /* CONFIG_LOOPW */
    
    
    U_BOOT_CMD(
    	mtest,    4,    1,     do_mem_mtest,
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    	"mtest   - simple RAM test\n",
    	"[start [end [pattern]]]\n"
    	"    - simple RAM read/write test\n"
    );
    
    
    #ifdef CONFIG_MX_CYCLIC
    U_BOOT_CMD(
    	mdc,     4,     1,      do_mem_mdc,
    	"mdc     - memory display cyclic\n",
    	"[.b, .w, .l] address count delay(ms)\n    - memory display cyclic\n"
    );
    
    U_BOOT_CMD(
    	mwc,     4,     1,      do_mem_mwc,
    	"mwc     - memory write cyclic\n",
    	"[.b, .w, .l] address value delay(ms)\n    - memory write cyclic\n"
    );
    #endif /* CONFIG_MX_CYCLIC */
    
    
    Wolfgang Denk's avatar
    Wolfgang Denk committed
    #endif