📄 monitor_cmd.c
字号:
return 0;
}
if (mode == SHORT_HELP)
{
short_help ("Set the terminal type");
return 0;
}
if (mode == LONG_HELP)
{
set_term_cmd (USAGE);
long_help ("\
The terminal command sets the type of the current terminal to that specified\n\
in the type argument. The only available terminal types are vt100 and dumb.\n\
This is used by the line editor to determine how to update the terminal\n\
display.\n");
example ("\
terminal dumb\n\
Sets the type of the current terminal to a dumb terminal.\n");
return 0;
}
if (argvect[1] == NULL || argvect[2] != NULL)
set_term_cmd (USAGE);
else
set_term_name (argvect[1]);
return 0;
}
int
reset_cmd (cmdmode_t mode)
{
if (mode == USAGE)
{
usage ("reset");
return 0;
}
if (mode == SHORT_HELP)
{
short_help ("Reset the board (not on all architectures).");
return 0;
}
if (mode == LONG_HELP)
{
reset_cmd (USAGE);
long_help ("\
The reset command resets the board. This may not be implemented\n\
on all architectures");
return 0;
}
if (argvect[1] != NULL)
{
reset_cmd (USAGE);
}
else
{
__reset ();
}
return 0;
}
#if HAVE_USAGE
int
memusage_cmd (cmdmode_t mode)
{
extern int sdata, _end;
if (mode == USAGE)
{
usage ("usage");
return 0;
}
if (mode == SHORT_HELP)
{
short_help ("Show monitor memory usage");
return 0;
}
if (mode == LONG_HELP)
{
memusage_cmd (USAGE);
long_help ("\
The usage command shows the amount of memory being used by the monitor,\n\
broken down by category. Despite its name, it has nothing to do with the\n\
usage of any other command.\n");
return 0;
}
if (argvect[1] != NULL)
{
return memusage_cmd (USAGE);
}
else
{
xprintf ("%d bytes were allocated with sbrk\n", (char *)sbrk (0) - (char *)&_end);
}
return 0;
}
#endif /* HAVE_USAGE */
int
disassemble_cmd (cmdmode_t mode)
{
#ifdef DISASSEMBLER
int x;
if (mode == USAGE)
{
usage ("disassemble [location]");
return 0;
}
if (mode == SHORT_HELP)
{
short_help ("Disassemble memory");
return 0;
}
if (mode == LONG_HELP)
{
disassemble_cmd (USAGE);
long_help ("\
The disassemble command disassembles the contents of memory. Because of the\n\
way breakpoints are handled, all instructions are shown and breakpoints are\n\
not visible in the disassembled code. The disassemble command takes zero\n\
or one argument. When called with zero arguments, it starts disassembling\n\
from the current (user program) pc. When called with a location, it starts\n\
disassembling from the specified location. When called after a previous\n\
call and with no arguments, it disassembles the next area of memory after\n\
the one previously disassembled.\n");
example ("\
disassemble 45667000\n\
Displays disassembled code starting at location 45667000.");
return 0;
}
if (argvect [1] != NULL && argvect[2] != NULL)
{
return disassemble_cmd (USAGE);
}
if(argvect [1] != NULL)
str2addr (argvect [1], &last_pc);
for (x = 0; x < 10; x++)
last_pc = do_dis (&last_pc);
flush_dis ();
#else
#warning "DISASSEMBLER not implemented"
xprintf ("disassembler not available\n");
#endif
return 0;
}
int
copy_cmd (cmdmode_t mode)
{
mem_addr_t src, dst;
target_register_t size;
if (mode == USAGE)
{
usage ("copy startaddr destaddr amount");
return 0;
}
if (mode == SHORT_HELP)
{
short_help ("Copies one area of memory to another");
return 0;
}
if (mode == LONG_HELP)
{
copy_cmd (USAGE);
long_help ("\
The copy command is used to copy 'amount' bytes of memory\n\
from 'startaddr' to 'destaddr'\n");
example ("\
copy 10000 20000 300\n\
Copies 0x300 bytes of memory from 0x10000 to 0x20000.");
return 0;
}
if (argvect[1] == NULL || argvect[2] == NULL || argvect[3] == NULL
|| argvect[4] != NULL)
{
return copy_cmd (USAGE);
}
str2addr (argvect[1], &src);
str2addr (argvect[2], &dst);
size = str2int (argvect[3], 16);
while (size > 0)
{
char buf[128];
int msize = (size > 128) ? 128 : size;
if (read_memory (&src, 1, msize, buf))
{
xprintf ("Memory read failed\n");
break;
}
if (write_memory (&dst, 1, msize, buf))
{
xprintf ("Memory write failed\n");
break;
}
#ifdef HAVE_BSP
bsp_flush_dcache((void *)dst.addr, msize);
bsp_flush_icache((void *)dst.addr, msize);
#endif
ADD_OFFSET (&src, &src, msize);
ADD_OFFSET (&dst, &dst, msize);
size -= msize;
}
return 0;
}
#ifndef HAVE_BSP
int
set_program_args_cmd (cmdmode_t mode)
{
int argc;
if (mode == USAGE)
{
usage ("setargs [args]");
return 0;
}
if (mode == SHORT_HELP)
{
short_help ("Sets the program arguments passed to main()");
return 0;
}
if (mode == LONG_HELP)
{
set_program_args_cmd (SHORT_HELP);
return 0;
}
for (argc = 1; argvect[argc] != NULL; argc++)
;
__set_program_args (argc - 1, argvect + 1);
return 0;
}
#endif
int
fill_cmd (cmdmode_t mode)
{
if (mode == USAGE)
{
usage ("fill[.size] startaddress endaddress [value]");
return 0;
}
if (mode == SHORT_HELP)
{
short_help ("Fills memory with a specified value");
return 0;
}
if (mode == LONG_HELP)
{
fill_cmd (USAGE);
long_help("\
The fill command is used to fill a region of memory from 'startaddress'\n\
to 'endaddress' with the value in 'value'. If no value is specificed,\n\
it uses zero. It can take a size extension, which follows the command\n\
name or partial command name without a space, and is a period followed\n\
by the size of the writes that are used, in bits. Options are 8, 16,\n\
32, and 64. Without a size extension, the fill command defaults to\n\
changing 8 bits at a time.\n");
example ("\
fill.32 10000 20000 32\n\
Fills the region between 0x10000 and 0x20000 with the 32 bit value 0x32.");
return 0;
}
if ((argvect[1] == NULL || argvect[2] == NULL)
|| (argvect[3] != NULL && argvect[4] != NULL))
{
fill_cmd (USAGE);
return 0;
} else {
mem_addr_t start,end;
char value[8];
int size = get_cmd_size();
int amt;
if (size == -1)
/*
* Invalid size specified.
*/
return 0;
if (argvect[3] != NULL)
{
hex2bytes (argvect[3], value, size);
}
else
{
hex2bytes ("0", value, size);
}
str2addr (argvect[1], &start);
str2addr (argvect[2], &end);
amt = MEM_ADDR_DIFF (end, start);
if (amt < 0)
{
xprintf ("Addresses in incorrect order\n");
}
else
{
int x;
if (get_memory_display_mode ())
{
/* Gotta swap this puppy. */
int x;
for (x = 0; x < (size / 2); x++)
{
char tmp = value[x];
value [x] = value [size - 1 - x];
value [size - 1 - x] = tmp;
}
}
xprintf ("Writing %d units\n", amt / size + 1);
for (x = amt / size; x >= 0; x--)
{
if (write_memory (&start, size, 1, value))
{
xprintf ("Memory write failed\n");
break;
}
ADD_OFFSET (&start, &start, size);
}
}
}
return 0;
}
int
swapmem_cmd (cmdmode_t mode)
{
int display_settings = 0;
if (mode == USAGE)
{
usage ("swapmem [little|big]");
return 0;
}
if (mode == SHORT_HELP)
{
short_help ("Sets whether or not memory values are byte-swapped");
return 0;
}
if (mode == LONG_HELP)
{
swapmem_cmd (USAGE);
long_help("\
The swapmem command is used to determine whether or not memory values are\n\
displayed and written in little or big-endian byte order. By default, values\n\
are read and written to match the byte order of the target CPU.\n\
This command does not alter the CPU state in any way; it only changes the\n\
way memory values are displayed and written within the monitor.\n");
example("\
swapmem \n\
Displays the byte order that is currently in effect.");
return 0;
display_settings = 1;
}
else
{
if (argvect[1] != NULL && argvect[2] != NULL)
{
swapmem_cmd (USAGE);
return 0;
}
}
if (display_settings || argvect[1] == NULL)
{
if (get_memory_display_mode ())
{
xprintf ("Memory values are read and written in little-endian byte order.\n");
}
else
{
xprintf ("Memory values are read and written in big-endian byte order.\n");
}
return 0;
}
if (strncmp (argvect[1], "little", strlen (argvect[1])) == 0)
{
set_memory_display_mode (1);
xprintf ("Memory values are now read and written in little-endian order.\n");
}
else if (strncmp (argvect[1], "big", strlen (argvect[1])) == 0)
{
set_memory_display_mode (0);
xprintf ("Memory values are now read and written in big-endian order.\n");
}
else
{
return swapmem_cmd (USAGE);
}
return 0;
}
#ifdef MONITOR_CONTROL_INTERRUPTS
int
int_cmd (cmdmode_t mode)
{
if (mode == USAGE)
{
usage ("interrupt [on|off]");
return 0;
}
if (mode == SHORT_HELP)
{
short_help ("Enables or disables interrupts within the monitor");
return 0;
}
if (mode == LONG_HELP)
{
int_cmd (USAGE);
long_help("\
The interrupt command is used to enable or disable interrupts while the\n\
monitor is running.");
return 0;
}
if (argvect[1] != NULL && argvect[2] != NULL)
{
int_cmd (USAGE);
return 0;
}
if (argvect[1] != NULL)
{
if (strcmp (argvect[1], "on") == 0)
{
monitor_enable_interrupts ();
}
else if (strcmp (argvect[1], "off") == 0)
{
monitor_disable_interrupts ();
}
else
{
int_cmd (USAGE);
return 0;
}
}
xprintf ("Interrupts ");
if (monitor_interrupt_state ())
{
xprintf ("enabled\n");
}
else
{
xprintf ("disabled\n");
}
return 0;
}
#endif
/* Table used by the crc32 function to calcuate the checksum. */
static uint32 crc32_table[256];
static int crc_initted = 0;
static uint32
crc32 (unsigned char *buf, int len, uint32 crc)
{
if (! crc_initted)
{
/* Initialize the CRC table and the decoding table. */
int i, j;
uint32 c;
crc_initted = 1;
for (i = 0; i < 256; i++)
{
for (c = i << 24, j = 8; j > 0; --j)
c = c & 0x80000000 ? (c << 1) ^ 0x04c11db7 : (c << 1);
crc32_table[i] = c;
}
}
while (len--)
{
crc = (crc << 8) ^ crc32_table[((crc >> 24) ^ *buf) & 255];
buf++;
}
return crc;
}
int
checksumcmd (cmdmode_t mode)
{
mem_addr_t start, end;
uint32 crc = 0xffffffff;
if (mode == USAGE)
{
usage ("crc startaddr endaddr");
return 0;
}
if (mode == SHORT_HELP)
{
short_help ("checksum an area of memory");
return 0;
}
if (mode == LONG_HELP)
{
checksumcmd (USAGE);
long_help ("\
The crc command is used to calculate a standard CRC32 checksum of the\n\
specified memory region. The checksum is printed out as a hexadecimal\n\
value.");
return 0;
}
if (argvect[1] == NULL || argvect[2] == NULL || argvect[3] != NULL)
{
return checksumcmd (USAGE);
}
str2addr (argvect[1], &start);
str2addr (argvect[2], &end);
while (start.addr < end.addr)
{
char c[1024];
int len = end.addr - start.addr;
if (len > sizeof(c))
len = sizeof(c);
read_memory (&start, 1, len, c);
crc = crc32 (c, len, crc);
start.addr += len;
}
xprintf("0x%08lx is checksum\n", crc);
return 0;
}
char **argvect;
static char argvect_cmd[MAXLINELEN];
static char **
buildargv (char *input)
{
static char *arglist[256];
int numargs = 0;
while (1)
{
while (isspace ((unsigned char)*input) && *input != 0)
input++;
if (*input == 0)
break;
arglist [numargs++] = input;
while (!isspace ((unsigned char)*input) && *input != 0)
input++;
if (*input == 0)
break;
*(input++) = 0;
}
arglist [numargs] = NULL;
return arglist;
}
int
monitor_loop (void)
{
int state = 1, return_value = 0;
while (state == 1)
{
/* Get a line of input, putting it in the input buffer */
lineedit (PROMPT, inbuf, sizeof (inbuf));
xprintf ("\n");
if (switch_to_stub_flag)
{
#ifndef HAVE_BSP
switch_to_stub_flag = 0;
#endif
return transfer_to_stub ();
}
/* Separate off the command from any other stuff on the line */
strcpy (argvect_cmd, inbuf);
argvect = buildargv (argvect_cmd);
if (argvect[0] != NULL && argvect[0][0] != '\0')
{
char *ptr;
int command_number;
strcpy (cmd, argvect[0]);
/* Function to split off . delimiters. */
ptr = strchr (cmd, '.');
if (ptr != NULL && *ptr == '.')
*ptr = '\0';
/* See if it's an alias. */
command_number = alias_compare (cmd);
/* Compare input to command list, check for conflicts. */
if (command_number < 0)
command_number = command_compare (cmd);
/* If we found a command, just run the function */
if (command_number >= 0)
{
int status;
/* Execute the function, if the function returns a non-zero
value, break out of the loop and return. */
status = (*cmdtab[command_number].function) (INVOCATION);
if (status)
{
state = 0;
if (status < 0)
return_value = 1;
}
}
else
{
/* If none of the commands or aliases match, complain. */
xprintf ("Not a legal command\n");
}
if (inbuf[0] != '\0')
addHistoryCmd (inbuf);
}
}
return return_value;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -