Newer
Older
/*
* (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>
#ifdef CONFIG_HAS_DATAFLASH
#include <dataflash.h>
#endif
#include <watchdog.h>
#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
#ifndef CONFIG_SYS_MEMTEST_SCRATCH
#define CONFIG_SYS_MEMTEST_SCRATCH 0
#endif
static int mod_mem(cmd_tbl_t *, int, int, int, char * const []);
/* Display values from last command.
* Memory modify remembered values are different from display memory.
*/
static uint dp_last_addr, dp_last_size;
static uint dp_last_length = 0x40;
static 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 16
static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
ulong addr, length;
#if defined(CONFIG_HAS_DATAFLASH)
ulong nbytes, linebytes;
#endif
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;
return CMD_RET_USAGE;
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;
/* 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);
}
#if defined(CONFIG_HAS_DATAFLASH)
/* 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];
void* p;
linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
rc = read_dataflash(addr, (linebytes/size)*size, linebuf);
p = (rc == DATAFLASH_OK) ? linebuf : (void*)addr;
print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size);
addr += linebytes;
if (ctrlc()) {
rc = 1;
break;
}
} while (nbytes > 0);
#else
# if defined(CONFIG_BLACKFIN)
/* See if we're trying to display L1 inst */
if (addr_bfin_on_chip_mem(addr)) {
char linebuf[DISP_LINE_LEN];
ulong linebytes, nbytes = length * size;
do {
linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
memcpy(linebuf, (void *)addr, linebytes);
print_buffer(addr, linebuf, size, linebytes/size, DISP_LINE_LEN/size);
nbytes -= linebytes;
addr += linebytes;
if (ctrlc()) {
rc = 1;
break;
}
} while (nbytes > 0);
} else
# endif
{
ulong bytes = size * length;
const void *buf = map_sysmem(addr, bytes);
/* Print the lines. */
print_buffer(addr, buf, size, length, DISP_LINE_LEN / size);
addr += bytes;
unmap_sysmem(buf);
#endif
dp_last_addr = addr;
dp_last_length = length;
dp_last_size = size;
return (rc);
}
static int do_mem_mm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
return mod_mem (cmdtp, 1, flag, argc, argv);
}
static int do_mem_nm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
return mod_mem (cmdtp, 0, flag, argc, argv);
}
static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
ulong addr, writeval, count;
int size;
void *buf;
ulong bytes;
if ((argc < 3) || (argc > 4))
return CMD_RET_USAGE;
if ((size = cmd_get_data_size(argv[0], 4)) < 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;
Loading
Loading full blame...