📄 memcmds.c
字号:
/* memcmds.c: * This code allows the monitor to display, modify, search, copy and fill * memory in a variety of different ways. * * General notice: * This code is part of a boot-monitor package developed as a generic base * platform for embedded system designs. As such, it is likely to be * distributed to various projects beyond the control of the original * author. Please notify the author of any enhancements made or bugs found * so that all may benefit from the changes. In addition, notification back * to the author will allow the new user to pick up changes that may have * been made by other users after this version of the code was distributed. * * Note1: the majority of this code was edited with 4-space tabs. * Note2: as more and more contributions are accepted, the term "author" * is becoming a mis-representation of credit. * * Original author: Ed Sutter * Email: esutter@lucent.com * Phone: 908-582-2351 */#include "config.h"#include "genlib.h"#include "stddefs.h"#include "cli.h"#if INCLUDE_MEMCMDS/* Pm(): * Put to memory. * * Arguments... * arg1: address. * arg2-argN: data to put beginning at specified address (max of 8). * * Options... * -2 access as a short. * -4 access as a long. * -f fifo access (address does not increment). * -s data is ascii string. * -S data is ascii string and should be concatenated with the * string that starts at the specified address. */char *PmHelp[] = { "Put to Memory", "-[24efsS] {addr} {val|string} [val] ...", " -2 short access", " -4 long access", " -e endian swap", " -f fifo mode", " -s strcpy", " -S strcat", 0,};intPm(int argc,char *argv[]){ ulong val4, add; ushort val2; uchar val1; int opt, width, ascii, fifo, i, j, concatenate, endian_swap; width = 1; ascii = fifo = 0; concatenate = 0; endian_swap = 0; while((opt=getopt(argc,argv,"24efsS")) != -1) { switch(opt) { case 's': ascii = 1; break; case 'S': ascii = 1; concatenate = 1; break; case 'e': endian_swap = 1; break; case 'f': fifo = 1; break; case '2': width = 2; break; case '4': width = 4; break; default: return(CMD_PARAM_ERROR); } } if (argc < (optind+2)) return(CMD_PARAM_ERROR); add = strtoul(argv[optind],(char **)0,0); if (ascii) { if (concatenate) { /* If concatenate, skip to */ while(*(uchar *)add) /* end of string, then start. */ add++; } for(i=optind+1;i<argc;i++) { j = 0; while(argv[i][j]) { *(uchar *)add = argv[i][j++]; if (!fifo) add++; } } *(uchar *)add = 0; return(CMD_SUCCESS); } for(i=optind+1;i<argc;i++) { switch(width) { case 1: val1 = (uchar)strtoul(argv[i],(char **)0,0); *(uchar *)add = val1; if (!fifo) add++; break; case 2: val2 = (ushort)strtoul(argv[i],(char **)0,0); *(ushort *)add = endian_swap ? swap2(val2) : val2; if (!fifo) add += 2; break; case 4: val4 = (ulong)strtoul(argv[i],(char **)0,0); *(ulong *)add = endian_swap ? swap4(val4) : val4; if (!fifo) add += 4; break; } } return(CMD_SUCCESS);}/* Dm(): * Display memory. * * Arguments... * arg1: address to start display * arg2: if present, specifies the number of units to be displayed. * * Options... * -2 a unit is a short. * -4 a unit is a long. * -b print chars out as is (binary). * -d display in decimal. * -e endian-swap for short/long display. * -f fifo-type access (address does not increment). * -m prompt user for more. * -s print chars out as is (binary) and terminates at a null. * -v {varname} assign last value displayed to shell var varname. * * Defaults... * Display in hex, and unit type is byte. */char *DmHelp[] = { "Display Memory", "-[24bdefs] {addr} [byte-cnt]", " -2 short access", " -4 long access", " -b binary", " -d decimal", " -e endian swap", " -f fifo mode", " -m use 'more'", " -s string", " -v {var} quietly load 'var' with element at addr", 0,};#define BD_NULL 0#define BD_RAWBINARY 1#define BD_ASCIISTRING 2intDm(int argc,char *argv[]){ int i, count, count_rqst, width, opt, more, size, fifo; int hex_display, bin_display, endian_swap; char *varname, *prfmt, *vprfmt; uchar *cp, cbuf[16]; ushort *sp; ulong *lp, add; width = 1; more = fifo = 0; bin_display = BD_NULL; hex_display = 1; endian_swap = 0; varname = (char *)0; while((opt=getopt(argc,argv,"24bdefmsv:")) != -1) { switch(opt) { case '2': width = 2; break; case '4': width = 4; break; case 'b': bin_display = BD_RAWBINARY; break; case 'd': hex_display = 0; break; case 'e': endian_swap = 1; break; case 'f': fifo = 1; break; case 'm': more = 1; break; case 'v': varname = optarg; break; case 's': bin_display = BD_ASCIISTRING; break; default: return(CMD_PARAM_ERROR); } } if (argc < (optind+1)) return(CMD_PARAM_ERROR); add = strtoul(argv[optind],(char **)0,0); if (hex_display) vprfmt = "0x%x"; else vprfmt = "%d"; if (argc-(optind-1) == 3) { count_rqst = strtoul(argv[optind+1],(char **)0,0); count_rqst *= width; } else count_rqst = 128; if (bin_display != BD_NULL) { cp = (uchar *)add; if (bin_display == BD_ASCIISTRING) { puts(cp); if (varname) { shell_sprintf(varname,vprfmt,cp+strlen(cp)+1); } } else { for(i=0;i<count_rqst;i++) putchar(*cp++); } putchar('\n'); return(CMD_SUCCESS); } do { count = count_rqst; if (width == 1) { cp = (uchar *)add; if (hex_display) prfmt = "%02X "; else prfmt = "%3d "; if (varname) { shell_sprintf(varname,vprfmt,*cp); } else { while(count > 0) { printf("%08lx: ",(ulong)cp); if (count > 16) size = 16; else size = count; for(i=0;i<16;i++) { if (i >= size) puts(" "); else { cbuf[i] = *cp; printf(prfmt,cbuf[i]); } if (i == 7) puts(" "); if (!fifo) cp++; } if ((hex_display) && (!fifo)) { puts(" "); prascii(cbuf,size); } putchar('\n'); count -= size; if (!fifo) { add += size; cp = (uchar *)add; } } } } else if (width == 2) { sp = (ushort *)add; if (hex_display) prfmt = "%04X "; else prfmt = "%5d "; if (varname) { shell_sprintf(varname,vprfmt,endian_swap ? swap2(*sp) : *sp); } else { while(count>0) { printf("%08lx: ",(ulong)sp); if (count > 16) size = 16; else size = count; for(i=0;i<size;i+=2) { printf(prfmt,endian_swap ? swap2(*sp) : *sp); if (!fifo) sp++; } putchar('\n'); count -= size; if (!fifo) { add += size; sp = (ushort *)add; } } } } else if (width == 4) { lp = (ulong *)add; if (hex_display) prfmt = "%08X "; else prfmt = "%12d "; if (varname) { shell_sprintf(varname,vprfmt,endian_swap ? swap4(*lp) : *lp); } else { while(count>0) { printf("%08lx: ",(ulong)lp); if (count > 16) size = 16; else size = count; for(i=0;i<size;i+=4) { printf(prfmt,endian_swap ? swap4(*lp) : *lp); if (!fifo) lp++; } putchar('\n'); count -= size; if (!fifo) { add += size; lp = (ulong *)add; } } } } } while (more && More()); return(CMD_SUCCESS);}/* Fm(): * Fill memory with user-specified data. * Syntax: * fm [options] {start} {count | finish} {value} */char *FmHelp[] = { "Fill Memory", "-[c24] {start} {finish|byte-cnt} {value}", " -c arg2 is count (in bytes)", " -2 short access", " -4 long access", 0,};intFm(int argc,char *argv[]){ ulong start, finish; uchar *cptr, cdata; ushort *wptr, wdata; ulong *lptr, ldata, error_at; int width, opt, arg2iscount, err; width = 1; error_at = 0; arg2iscount = 0; while((opt=getopt(argc,argv,"24c")) != -1) { switch(opt) { case '2': width = 2; break; case '4': width = 4; break; case 'c': arg2iscount = 1; break; default: return(CMD_PARAM_ERROR); } } start = strtoul(argv[optind],(char **)0,0); finish = strtoul(argv[optind+1],(char **)0,0); if (arg2iscount) finish = start + finish; err = 0; switch (width) { case 1: cdata = (uchar) strtoul(argv[optind+2],0,0); for(cptr=(uchar *)start;cptr<(uchar *)finish;cptr++) { *cptr = cdata; if (*cptr != cdata) { err = 1; error_at = (ulong)cptr; break; } } break; case 2: wdata = (ushort) strtoul(argv[optind+2],0,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -