/*-----------------------------------------------------------*/
|
//////////////////////////////////////////////////////////////////////
|
|
//// ////
|
|
//// Copyright (C) 2015 Authors and OPENCORES.ORG ////
|
|
//// ////
|
|
//// This source file may be used and distributed without ////
|
|
//// restriction provided that this copyright statement is not ////
|
|
//// removed from the file and that any derivative work contains ////
|
|
//// the original copyright notice and the associated disclaimer. ////
|
|
//// ////
|
|
//// This source file is free software; you can redistribute it ////
|
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
|
//// Public License as published by the Free Software Foundation; ////
|
|
//// either version 2.1 of the License, or (at your option) any ////
|
|
//// later version. ////
|
|
//// ////
|
|
//// This source 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 Lesser General Public License for more ////
|
|
//// details. ////
|
|
//// ////
|
|
//// You should have received a copy of the GNU Lesser General ////
|
|
//// Public License along with this source; if not, download it ////
|
|
//// from http://www.opencores.org/lgpl.shtml ////
|
|
//// ////
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
#include "util_mem.h"
|
#include "util_mem.h"
|
|
|
|
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
|
|
/* Display values from last command.
|
/* Display values from last command.
|
* Memory modify remembered values are different from display memory.
|
* Memory modify remembered values are different from display memory.
|
*/
|
*/
|
static ulong dp_last_addr, dp_last_size;
|
static ulong dp_last_addr, dp_last_size;
|
static ulong dp_last_length = 0x40;
|
static ulong dp_last_length = 0x40;
|
// static ulong mm_last_addr, mm_last_size;
|
// static ulong mm_last_addr, mm_last_size;
|
|
|
static ulong base_address = 0;
|
static ulong base_address = 0;
|
|
|
/* Memory Display
|
/* Memory Display
|
*
|
*
|
* Syntax:
|
* Syntax:
|
* md{.b, .w, .l, .q} {addr} {len}
|
* md{.b, .w, .l, .q} {addr} {len}
|
*/
|
*/
|
#define DISP_LINE_LEN 16
|
#define DISP_LINE_LEN 16
|
static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, const char * argv[])
|
static int do_mem_md(cmd_tbl_t *cmdtp, int flag, int argc, const char * argv[])
|
{
|
{
|
ulong addr, length;
|
ulong addr, length;
|
#if defined(CONFIG_HAS_DATAFLASH)
|
#if defined(CONFIG_HAS_DATAFLASH)
|
ulong nbytes, linebytes;
|
ulong nbytes, linebytes;
|
#endif
|
#endif
|
int size;
|
int size;
|
int rc = 0;
|
int rc = 0;
|
|
|
/* We use the last specified parameters, unless new ones are
|
/* We use the last specified parameters, unless new ones are
|
* entered.
|
* entered.
|
*/
|
*/
|
addr = dp_last_addr;
|
addr = dp_last_addr;
|
size = dp_last_size;
|
size = dp_last_size;
|
length = dp_last_length;
|
length = dp_last_length;
|
|
|
if (argc < 2)
|
if (argc < 2)
|
return CMD_RET_USAGE;
|
return CMD_RET_USAGE;
|
|
|
if ((flag & CMD_FLAG_REPEAT) == 0) {
|
if ((flag & CMD_FLAG_REPEAT) == 0) {
|
/* New command specified. Check for a size specification.
|
/* New command specified. Check for a size specification.
|
* Defaults to long if no or incorrect specification.
|
* Defaults to long if no or incorrect specification.
|
*/
|
*/
|
if ((size = cmd_get_data_size(argv[0], 4)) < 0)
|
if ((size = cmd_get_data_size(argv[0], 4)) < 0)
|
return 1;
|
return 1;
|
|
|
/* Address is specified since argc > 1
|
/* Address is specified since argc > 1
|
*/
|
*/
|
addr = simple_strtoul(argv[1], NULL, 16);
|
addr = simple_strtoul(argv[1], NULL, 16);
|
addr += base_address;
|
addr += base_address;
|
|
|
/* If another parameter, it is the length to display.
|
/* If another parameter, it is the length to display.
|
* Length is the number of objects, not number of bytes.
|
* Length is the number of objects, not number of bytes.
|
*/
|
*/
|
if (argc > 2)
|
if (argc > 2)
|
length = simple_strtoul(argv[2], NULL, 16);
|
length = simple_strtoul(argv[2], NULL, 16);
|
}
|
}
|
|
|
#if defined(CONFIG_HAS_DATAFLASH)
|
#if defined(CONFIG_HAS_DATAFLASH)
|
/* Print the lines.
|
/* Print the lines.
|
*
|
*
|
* We buffer all read data, so we can make sure data is read only
|
* We buffer all read data, so we can make sure data is read only
|
* once, and all accesses are with the specified bus width.
|
* once, and all accesses are with the specified bus width.
|
*/
|
*/
|
nbytes = length * size;
|
nbytes = length * size;
|
do {
|
do {
|
char linebuf[DISP_LINE_LEN];
|
char linebuf[DISP_LINE_LEN];
|
void* p;
|
void* p;
|
linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
|
linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
|
|
|
rc = read_dataflash(addr, (linebytes/size)*size, linebuf);
|
rc = read_dataflash(addr, (linebytes/size)*size, linebuf);
|
p = (rc == DATAFLASH_OK) ? linebuf : (void*)addr;
|
p = (rc == DATAFLASH_OK) ? linebuf : (void*)addr;
|
print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size);
|
print_buffer(addr, p, size, linebytes/size, DISP_LINE_LEN/size);
|
|
|
nbytes -= linebytes;
|
nbytes -= linebytes;
|
addr += linebytes;
|
addr += linebytes;
|
if (ctrlc()) {
|
if (ctrlc()) {
|
rc = 1;
|
rc = 1;
|
break;
|
break;
|
}
|
}
|
} while (nbytes > 0);
|
} while (nbytes > 0);
|
#else
|
#else
|
|
|
# if defined(CONFIG_BLACKFIN)
|
# if defined(CONFIG_BLACKFIN)
|
/* See if we're trying to display L1 inst */
|
/* See if we're trying to display L1 inst */
|
if (addr_bfin_on_chip_mem(addr)) {
|
if (addr_bfin_on_chip_mem(addr)) {
|
char linebuf[DISP_LINE_LEN];
|
char linebuf[DISP_LINE_LEN];
|
ulong linebytes, nbytes = length * size;
|
ulong linebytes, nbytes = length * size;
|
do {
|
do {
|
linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
|
linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
|
memcpy(linebuf, (void *)addr, linebytes);
|
memcpy(linebuf, (void *)addr, linebytes);
|
print_buffer(addr, linebuf, size, linebytes/size, DISP_LINE_LEN/size);
|
print_buffer(addr, linebuf, size, linebytes/size, DISP_LINE_LEN/size);
|
|
|
nbytes -= linebytes;
|
nbytes -= linebytes;
|
addr += linebytes;
|
addr += linebytes;
|
if (ctrlc()) {
|
if (ctrlc()) {
|
rc = 1;
|
rc = 1;
|
break;
|
break;
|
}
|
}
|
} while (nbytes > 0);
|
} while (nbytes > 0);
|
} else
|
} else
|
# endif
|
# endif
|
|
|
{
|
{
|
ulong bytes = size * length;
|
ulong bytes = size * length;
|
const void *buf = map_sysmem(addr, bytes);
|
const void *buf = map_sysmem(addr, bytes);
|
|
|
/* Print the lines. */
|
/* Print the lines. */
|
print_buffer(addr, buf, size, length, DISP_LINE_LEN / size);
|
print_buffer(addr, buf, size, length, DISP_LINE_LEN / size);
|
addr += bytes;
|
addr += bytes;
|
unmap_sysmem(buf);
|
unmap_sysmem(buf);
|
}
|
}
|
#endif
|
#endif
|
|
|
dp_last_addr = addr;
|
dp_last_addr = addr;
|
dp_last_length = length;
|
dp_last_length = length;
|
dp_last_size = size;
|
dp_last_size = size;
|
return (rc);
|
return (rc);
|
}
|
}
|
|
|
|
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, const char * argv[])
|
static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, const char * argv[])
|
{
|
{
|
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
|
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
|
u64 writeval;
|
u64 writeval;
|
#else
|
#else
|
ulong writeval;
|
ulong writeval;
|
#endif
|
#endif
|
ulong addr, count;
|
ulong addr, count;
|
int size;
|
int size;
|
void *buf, *start;
|
void *buf, *start;
|
ulong bytes;
|
ulong bytes;
|
|
|
if ((argc < 3) || (argc > 4))
|
if ((argc < 3) || (argc > 4))
|
return CMD_RET_USAGE;
|
return CMD_RET_USAGE;
|
|
|
/* Check for size specification.
|
/* Check for size specification.
|
*/
|
*/
|
if ((size = cmd_get_data_size(argv[0], 4)) < 1)
|
if ((size = cmd_get_data_size(argv[0], 4)) < 1)
|
return 1;
|
return 1;
|
|
|
/* Address is specified since argc > 1
|
/* Address is specified since argc > 1
|
*/
|
*/
|
addr = simple_strtoul(argv[1], NULL, 16);
|
addr = simple_strtoul(argv[1], NULL, 16);
|
addr += base_address;
|
addr += base_address;
|
|
|
/* Get the value to write.
|
/* Get the value to write.
|
*/
|
*/
|
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
|
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
|
writeval = simple_strtoull(argv[2], NULL, 16);
|
writeval = simple_strtoull(argv[2], NULL, 16);
|
#else
|
#else
|
writeval = simple_strtoul(argv[2], NULL, 16);
|
writeval = simple_strtoul(argv[2], NULL, 16);
|
#endif
|
#endif
|
|
|
/* Count ? */
|
/* Count ? */
|
if (argc == 4) {
|
if (argc == 4) {
|
count = simple_strtoul(argv[3], NULL, 16);
|
count = simple_strtoul(argv[3], NULL, 16);
|
} else {
|
} else {
|
count = 1;
|
count = 1;
|
}
|
}
|
|
|
bytes = size * count;
|
bytes = size * count;
|
start = map_sysmem(addr, bytes);
|
start = map_sysmem(addr, bytes);
|
buf = start;
|
buf = start;
|
while (count-- > 0) {
|
while (count-- > 0) {
|
if (size == 4)
|
if (size == 4)
|
*((u32 *)buf) = (u32)writeval;
|
*((u32 *)buf) = (u32)writeval;
|
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
|
#ifdef CONFIG_SYS_SUPPORT_64BIT_DATA
|
else if (size == 8)
|
else if (size == 8)
|
*((u64 *)buf) = (u64)writeval;
|
*((u64 *)buf) = (u64)writeval;
|
#endif
|
#endif
|
else if (size == 2)
|
else if (size == 2)
|
*((u16 *)buf) = (u16)writeval;
|
*((u16 *)buf) = (u16)writeval;
|
else
|
else
|
*((u8 *)buf) = (u8)writeval;
|
*((u8 *)buf) = (u8)writeval;
|
buf += size;
|
buf += size;
|
}
|
}
|
unmap_sysmem(start);
|
unmap_sysmem(start);
|
return 0;
|
return 0;
|
}
|
}
|
|
|
|
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
char func_mw( const unsigned char argc, const char *argv[] )
|
char func_mw( const unsigned char argc, const char *argv[] )
|
{
|
{
|
return do_mem_mw(0, 0, argc, argv);
|
return do_mem_mw(0, 0, argc, argv);
|
}
|
}
|
|
|
|
|
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
char func_md( const unsigned char argc, const char *argv[] )
|
char func_md( const unsigned char argc, const char *argv[] )
|
{
|
{
|
return do_mem_md(0, 0, argc, argv);
|
return do_mem_md(0, 0, argc, argv);
|
}
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|