⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmd_mem.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA *//* * Memory Functions * * Copied from FADS ROM, Dan Malek (dmalek@jlc.net) */#include <common.h>#include <command.h>#if (CONFIG_COMMANDS & CFG_CMD_MMC)#include <mmc.h>#endif#ifdef CONFIG_HAS_DATAFLASH#include <dataflash.h>#endif#if (CONFIG_COMMANDS & (CFG_CMD_MEMORY	| \			CFG_CMD_I2C	| \			CFG_CMD_ITEST	| \			CFG_CMD_PCI	| \			CMD_CMD_PORTIO	) )int cmd_get_data_size(char* arg, int default_size){	/* Check for a size specification .b, .w or .l.	 */	int len = strlen(arg);	if (len > 2 && arg[len-2] == '.') {		switch(arg[len-1]) {		case 'b':			return 1;		case 'w':			return 2;		case 'l':			return 4;		case 's':			return -2;		default:			return -1;		}	}	return default_size;}#endif#if (CONFIG_COMMANDS & CFG_CMD_MEMORY)#ifdef	CMD_MEM_DEBUG#define	PRINTF(fmt,args...)	printf (fmt ,##args)#else#define PRINTF(fmt,args...)#endifstatic int mod_mem(cmd_tbl_t *, int, int, int, char *[]);/* Display values from last command. * Memory modify remembered values are different from display memory. */uint	dp_last_addr, dp_last_size;uint	dp_last_length = 0x40;uint	mm_last_addr, mm_last_size;static	ulong	base_address = 0;/* Memory Display * * Syntax: *	md{.b, .w, .l} {addr} {len} */#define DISP_LINE_LEN	16int do_mem_md ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	ulong	addr, length;	ulong	i, nbytes, linebytes;	u_char	*cp;	int	size;	int rc = 0;	/* We use the last specified parameters, unless new ones are	 * entered.	 */	addr = dp_last_addr;	size = dp_last_size;	length = dp_last_length;	if (argc < 2) {		printf ("Usage:\n%s\n", cmdtp->usage);		return 1;	}	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], 1)) < 0)			return 1;		/* Address is specified since argc > 1		*/		addr = simple_strtoul(argv[1], NULL, 16);		addr += base_address;		/* If another parameter, it is the length to display.		 * Length is the number of objects, not number of bytes.		 */		if (argc > 2)			length = simple_strtoul(argv[2], NULL, 16);	}	/* Print the lines.	 *	 * We buffer all read data, so we can make sure data is read only	 * once, and all accesses are with the specified bus width.	 */	nbytes = length * size;	do {		char	linebuf[DISP_LINE_LEN];		uint	*uip = (uint   *)linebuf;		ushort	*usp = (ushort *)linebuf;		u_char	*ucp = (u_char *)linebuf;#ifdef CONFIG_HAS_DATAFLASH		int rc;#endif		printf("%08lx:", addr);		linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;#ifdef CONFIG_HAS_DATAFLASH		if ((rc = read_dataflash(addr, (linebytes/size)*size, linebuf)) == DATAFLASH_OK){			/* if outside dataflash */			/*if (rc != 1) {				dataflash_perror (rc);				return (1);			}*/			for (i=0; i<linebytes; i+= size) {				if (size == 4) {					printf(" %08x", *uip++);				} else if (size == 2) {					printf(" %04x", *usp++);				} else {					printf(" %02x", *ucp++);				}				addr += size;			}		} else {	/* addr does not correspond to DataFlash */#endif		for (i=0; i<linebytes; i+= size) {			if (size == 4) {				printf(" %08x", (*uip++ = *((uint *)addr)));			} else if (size == 2) {				printf(" %04x", (*usp++ = *((ushort *)addr)));			} else {				printf(" %02x", (*ucp++ = *((u_char *)addr)));			}			addr += size;		}#ifdef CONFIG_HAS_DATAFLASH		}#endif		puts ("    ");		cp = linebuf;		for (i=0; i<linebytes; i++) {			if ((*cp < 0x20) || (*cp > 0x7e))				putc ('.');			else				printf("%c", *cp);			cp++;		}		putc ('\n');		nbytes -= linebytes;		if (ctrlc()) {			rc = 1;			break;		}	} while (nbytes > 0);	dp_last_addr = addr;	dp_last_length = length;	dp_last_size = size;	return (rc);}int do_mem_mm ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	return mod_mem (cmdtp, 1, flag, argc, argv);}int do_mem_nm ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	return mod_mem (cmdtp, 0, flag, argc, argv);}int do_mem_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	ulong	addr, writeval, count;	int	size;	if ((argc < 3) || (argc > 4)) {		printf ("Usage:\n%s\n", cmdtp->usage);		return 1;	}	/* Check for size specification.	*/	if ((size = cmd_get_data_size(argv[0], 1)) < 1)		return 1;	/* Address is specified since argc > 1	*/	addr = simple_strtoul(argv[1], NULL, 16);	addr += base_address;	/* Get the value to write.	*/	writeval = simple_strtoul(argv[2], NULL, 16);	/* Count ? */	if (argc == 4) {		count = simple_strtoul(argv[3], NULL, 16);	} else {		count = 1;	}	while (count-- > 0) {		if (size == 4)			*((ulong  *)addr) = (ulong )writeval;		else if (size == 2)			*((ushort *)addr) = (ushort)writeval;		else			*((u_char *)addr) = (u_char)writeval;		addr += size;	}	return 0;}#ifdef CONFIG_MX_CYCLICint do_mem_mdc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	int i;	ulong count;	if (argc < 4) {		printf ("Usage:\n%s\n", cmdtp->usage);		return 1;	}	count = simple_strtoul(argv[3], NULL, 10);	for (;;) {		do_mem_md (NULL, 0, 3, argv);		/* delay for <count> ms... */		for (i=0; i<count; i++)			udelay (1000);		/* check for ctrl-c to abort... */		if (ctrlc()) {			puts("Abort\n");			return 0;		}	}	return 0;}int do_mem_mwc ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	int i;	ulong count;	if (argc < 4) {		printf ("Usage:\n%s\n", cmdtp->usage);		return 1;	}	count = simple_strtoul(argv[3], NULL, 10);	for (;;) {		do_mem_mw (NULL, 0, 3, argv);		/* delay for <count> ms... */		for (i=0; i<count; i++)			udelay (1000);		/* check for ctrl-c to abort... */		if (ctrlc()) {			puts("Abort\n");			return 0;		}	}	return 0;}#endif /* CONFIG_MX_CYCLIC */int do_mem_cmp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	ulong	addr1, addr2, count, ngood;	int	size;	int     rcode = 0;	if (argc != 4) {		printf ("Usage:\n%s\n", cmdtp->usage);		return 1;	}	/* Check for size specification.	*/	if ((size = cmd_get_data_size(argv[0], 1)) < 0)		return 1;	addr1 = simple_strtoul(argv[1], NULL, 16);	addr1 += base_address;	addr2 = simple_strtoul(argv[2], NULL, 16);	addr2 += base_address;	count = simple_strtoul(argv[3], NULL, 16);#ifdef CONFIG_HAS_DATAFLASH	if (addr_dataflash(addr1) | addr_dataflash(addr2)){		puts ("Comparison with DataFlash space not supported.\n\r");		return 0;	}#endif	ngood = 0;	while (count-- > 0) {		if (size == 4) {			ulong word1 = *(ulong *)addr1;			ulong word2 = *(ulong *)addr2;			if (word1 != word2) {				printf("word at 0x%08lx (0x%08lx) "					"!= word at 0x%08lx (0x%08lx)\n",					addr1, word1, addr2, word2);				rcode = 1;				break;			}		}		else if (size == 2) {			ushort hword1 = *(ushort *)addr1;			ushort hword2 = *(ushort *)addr2;			if (hword1 != hword2) {				printf("halfword at 0x%08lx (0x%04x) "					"!= halfword at 0x%08lx (0x%04x)\n",					addr1, hword1, addr2, hword2);				rcode = 1;				break;			}		}		else {			u_char byte1 = *(u_char *)addr1;			u_char byte2 = *(u_char *)addr2;			if (byte1 != byte2) {				printf("byte at 0x%08lx (0x%02x) "					"!= byte at 0x%08lx (0x%02x)\n",					addr1, byte1, addr2, byte2);				rcode = 1;				break;			}		}		ngood++;		addr1 += size;		addr2 += size;	}	printf("Total of %ld %s%s were the same\n",		ngood, size == 4 ? "word" : size == 2 ? "halfword" : "byte",		ngood == 1 ? "" : "s");	return rcode;}int do_mem_cp ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	ulong	addr, dest, count;	int	size;	if (argc != 4) {		printf ("Usage:\n%s\n", cmdtp->usage);		return 1;	}	/* Check for size specification.	*/	if ((size = cmd_get_data_size(argv[0], 1)) < 0)		return 1;	addr = simple_strtoul(argv[1], NULL, 16);	addr += base_address;	dest = simple_strtoul(argv[2], NULL, 16);	dest += base_address;	count = simple_strtoul(argv[3], NULL, 16);	if (count == 0) {		puts ("Zero length ???\n");		return 1;	}#ifndef CFG_NO_FLASH	/* check if we are copying to Flash */	if ( (addr2info(dest) != NULL)#ifdef CONFIG_HAS_DATAFLASH	   && (!addr_dataflash(addr))#endif	   ) {		int rc;		puts ("Copy to Flash... ");		rc = flash_write ((uchar *)addr, dest, count*size);		if (rc != 0) {			flash_perror (rc);			return (1);		}		puts ("done\n");		return 0;	}#endif#if (CONFIG_COMMANDS & CFG_CMD_MMC)	if (mmc2info(dest)) {		int rc;		puts ("Copy to MMC... ");		switch (rc = mmc_write ((uchar *)addr, dest, count*size)) {		case 0:			putc ('\n');			return 1;		case -1:			puts ("failed\n");			return 1;		default:			printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc);			return 1;		}		puts ("done\n");		return 0;	}	if (mmc2info(addr)) {		int rc;		puts ("Copy from MMC... ");		switch (rc = mmc_read (addr, (uchar *)dest, count*size)) {		case 0:			putc ('\n');			return 1;		case -1:			puts ("failed\n");			return 1;		default:			printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc);			return 1;		}		puts ("done\n");		return 0;	}#endif#ifdef CONFIG_HAS_DATAFLASH	/* Check if we are copying from RAM or Flash to DataFlash */	if (addr_dataflash(dest) && !addr_dataflash(addr)){		int rc;		puts ("Copy to DataFlash... ");		rc = write_dataflash (dest, addr, count*size);		if (rc != 1) {			dataflash_perror (rc);			return (1);		}		puts ("done\n");		return 0;	}	/* Check if we are copying from DataFlash to RAM */	if (addr_dataflash(addr) && !addr_dataflash(dest) && (addr2info(dest)==NULL) ){		int rc;		rc = read_dataflash(addr, count * size, (char *) dest);		if (rc != 1) {			dataflash_perror (rc);			return (1);		}		return 0;	}	if (addr_dataflash(addr) && addr_dataflash(dest)){		puts ("Unsupported combination of source/destination.\n\r");		return 1;	}#endif	while (count-- > 0) {		if (size == 4)			*((ulong  *)dest) = *((ulong  *)addr);		else if (size == 2)			*((ushort *)dest) = *((ushort *)addr);		else			*((u_char *)dest) = *((u_char *)addr);		addr += size;		dest += size;	}	return 0;}int do_mem_base (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	if (argc > 1) {		/* Set new base address.		*/		base_address = simple_strtoul(argv[1], NULL, 16);	}	/* Print the current base address.	*/	printf("Base Address: 0x%08lx\n", base_address);	return 0;}int do_mem_loop (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	ulong	addr, length, i, junk;	int	size;	volatile uint	*longp;	volatile ushort *shortp;	volatile u_char	*cp;	if (argc < 3) {		printf ("Usage:\n%s\n", cmdtp->usage);		return 1;	}	/* Check for a size spefication.	 * Defaults to long if no or incorrect specification.	 */	if ((size = cmd_get_data_size(argv[0], 1)) < 0)		return 1;	/* Address is always specified.	*/	addr = simple_strtoul(argv[1], NULL, 16);	/* Length is the number of objects, not number of bytes.	*/	length = simple_strtoul(argv[2], NULL, 16);	/* We want to optimize the loops to run as fast as possible.	 * If we have only one object, just run infinite loops.	 */	if (length == 1) {		if (size == 4) {			longp = (uint *)addr;			for (;;)				i = *longp;		}		if (size == 2) {			shortp = (ushort *)addr;			for (;;)				i = *shortp;		}		cp = (u_char *)addr;		for (;;)			i = *cp;	}	if (size == 4) {		for (;;) {			longp = (uint *)addr;			i = length;			while (i-- > 0)				junk = *longp++;		}	}	if (size == 2) {		for (;;) {			shortp = (ushort *)addr;			i = length;			while (i-- > 0)				junk = *shortp++;		}	}	for (;;) {		cp = (u_char *)addr;		i = length;		while (i-- > 0)			junk = *cp++;	}}#ifdef CONFIG_LOOPWint do_mem_loopw (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	ulong	addr, length, i, data;	int	size;	volatile uint	*longp;	volatile ushort *shortp;	volatile u_char	*cp;	if (argc < 4) {		printf ("Usage:\n%s\n", cmdtp->usage);		return 1;	}	/* Check for a size spefication.	 * Defaults to long if no or incorrect specification.	 */	if ((size = cmd_get_data_size(argv[0], 1)) < 0)		return 1;	/* Address is always specified.	*/	addr = simple_strtoul(argv[1], NULL, 16);	/* Length is the number of objects, not number of bytes.	*/	length = simple_strtoul(argv[2], NULL, 16);	/* data to write */	data = simple_strtoul(argv[3], NULL, 16);	/* We want to optimize the loops to run as fast as possible.	 * If we have only one object, just run infinite loops.	 */	if (length == 1) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -