reg_cache.c
来自「umon bootloader source code, support mip」· C语言 代码 · 共 212 行
C
212 行
/* reg_cache.c:
* Allow the user to display CPU registers that are locally cached
* when an exception is hit. These registers are not the currently
* active registers in the CPU context; rather, a copy of the context at
* the time of the most recent breakpoint or exception.
*
* 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 "cpu.h"
#include "genlib.h"
#include "ctype.h"
#include "stddefs.h"
#include "regnames.c"
#include "cli.h"
/* The file regnames.c will contain a table of character pointers that
* corresond to registers that are stored away by the target's exception
* handler. The table of names and the order in which the registers are
* stored by the exception handler must be synchronized.
* An example table is as follows (taken from FADS-MPC860 target)...
*
* static char *regnames[] = {
* "R0", "R1", "R2", "R3",
* "R4", "R5", "R6", "R7",
* "R8", "R9", "R10", "R11",
* "R12", "R13", "R14", "R15",
* "R16", "R17", "R18", "R19",
* "R20", "R21", "R22", "R23",
* "R24", "R25", "R26", "R27",
* "R28", "R29", "R30", "R31",
* "MSR", "CR", "LR", "XER",
* "DAR", "DSISR", "SRR0", "SRR1",
* "CTR", "DEC", "TBL", "TBU",
* "SPRG0", "SPRG1", "SPRG2", "SPRG3",
* };
*
* The real definition of this array would be in the file regnames.c in
* the target-specific directory.
*/
#define REGTOT (sizeof regnames/sizeof(char *))
/* regtbl[]:
* This array is used to store the actual register values. Storage
* is done by the target's exception handler and must match the order
* of the register names in the regnames[] array.
*/
ulong regtbl[REGTOT];
void
flushRegtbl(void)
{
flushDcache((char *)regtbl,sizeof(regtbl));
}
/* regidx():
* Return an index into the regnames[] array that matches the
* incoming register name.
* If no match is found, print an error message and return -1.
*/
static int
regidx(char *name)
{
int i;
strtoupper(name);
for(i=0;i<REGTOT;i++) {
if (!strcmp(name,regnames[i])) {
return(i);
}
}
printf("Bad reg: '%s'\n",name);
return(-1);
}
/* putreg():
* Put the specified value into the specified register
* storage location.
*/
int
putreg(char *name,ulong value)
{
int idx;
if ((idx = regidx(name)) == -1)
return(-1);
regtbl[idx] = value;
return(0);
}
/* getreg():
* Retrieve the value of the specified register.
*/
int
getreg(char *name,ulong *value)
{
int idx;
if ((idx = regidx(name)) == -1)
return(-1);
*value = regtbl[idx];
return(0);
}
/* showregs():
* Dump the content of the register cache in a tabular format
* showing the entry in the regnames[] array and the corresponding
* entry in the regtbl[] array.
*/
void
showregs(void)
{
int i, j;
for(i=0;i<REGTOT;) {
for(j=0;((j<4) && (i<REGTOT));j++,i++)
printf("%6s=0x%08lx ",regnames[i],regtbl[i]);
printf("\n");
}
}
/* reginit():
* Clear the register cache.
*/
void
reginit(void)
{
int i;
for(i=0;i<REGTOT;i++)
regtbl[i] = 0;
}
#if INCLUDE_STRACE
char *RegHelp[] = {
"Display/modify content of monitor's register cache",
"-[v:] [regname] [value]",
#if INCLUDE_VERBOSEHELP
"Options:",
" -v {var} quietly load 'var' with register content",
#endif
0,
};
int
Reg(int argc,char *argv[])
{
ulong reg;
int opt, i, forscript;
char *varname, buf[32];
forscript = 0;
varname = (char *)0;
while((opt=getopt(argc,argv,"sv:")) != -1) {
switch(opt) {
case 's':
forscript = 1;
break;
case 'v':
varname = optarg;
break;
default:
return(CMD_PARAM_ERROR);
}
}
if (argc == optind) {
if (forscript) {
for(i=0;i<REGTOT;i++)
printf("reg %s 0x%lx\n",regnames[i],regtbl[i]);
}
else
showregs();
return(CMD_SUCCESS);
}
else if (argc == optind + 1) {
if (getreg(argv[optind],®) != -1) {
sprintf(buf,"0x%lx",reg);
if (varname)
setenv(varname,buf);
else
printf("%s = %s\n",argv[optind],buf);
}
}
else if (argc == optind + 2) {
putreg(argv[1],strtol(argv[optind+1],(char **)0,0));
}
else {
return(CMD_PARAM_ERROR);
}
return(CMD_SUCCESS);
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?