⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 2 页
字号:
/* At description: *  The 'at' command provides a state-machine-like ability *  for breakpoints.  It uses the breakpoint trap as a way *  of entering the monitor from active application.  Upon *  entry into the monitor, a few different things can happen: * *  1. an action can be taken and then application is resumed; *  2. a condition is checked and if the condition is met, an *     action is taken; * *  It is basically an elaboration of the counting breakpoint (break *  at address HHHH the Nth time).  The counting breakpoint uses the *  break trap to temporarily enter the monitor, change some debug *  state, and, if the state meets some condition (in this case, the  *  count is met), then break; else resume application. * *  Note that several action/condition combinations can be done for *  a single address.  This allows the state machine to be as complex *  as necessary.  The sequence of the action/conditions is changeable. * *  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 "cpuio.h"#include "genlib.h"#if INCLUDE_DEBUG#include "ctype.h"#include "stddefs.h"#include "cli.h"extern  void    StepOverTrap(), resume(), putreg();ulong   PCatBreak;          /* Copy of PC at the breakpoint */ushort  settrap();/* Use TRAP for breakpoint */#define TRAPNUM     0#define TRAPU       0x4e#define TRAPL       (0x40+TRAPNUM)#define ATVARTOT    8   /* Number of AT variables */#define ATLISTSIZE  8   /* Number of AT statements *//* Action definitions: */#define VAR_INC     1   /* increment variable: VAR++ */#define VAR_DEC     2   /* decrement variable: VAR-- */#define VAR_EQ      3   /* assign variable: VAR=vv */#define FLG_SET     4   /* set flag: FSETff */#define FLG_CLR     5   /* clear flag: FCLRff */#define FLG_EQ      6   /* set flag: FEQff */#define BREAK       8   /* break: BRK *//* Condition definitions: */#define VAR_EQ_CONST    20  /* Atvar equals constant */#define VAR_EQ_LOC  21      /* Atvar equals content of location */#define FLG_ALL_SET 22      /* Atflag has all specified bits set */#define FLG_ANY_SET 23      /* Atflag has any specified bits set */#define FLG_EQ_CONST    24  /* Atflag equals constant */#define PASS_COUNT  26      /* At passcount equals constant */#define FUNC_CALL   27      /* At function returns constant */int atinit(), atlist();int ata(), atca();int atvarset(), atflagset(), atdelete(), atswap();static  ulong   atvars[ATVARTOT];static  ushort  atflag;struct atstruct {    uchar   inuse;      /* Set if this 'at' structure is in use. */    ushort  origtext;   /* Value in text prior to TRAP insertion */    ulong   address;    /* Address of breakpoint */    ushort  Condition;  /* Condition that will cause action */    ushort  Cvar;       /* Variable upon which condition is tested */    ulong   Cconst;     /* Constant used in condition */    ulong   Cadd;       /* Address used in condition */    ushort  Csize;      /* Size used in condition */    int Cpcnt;          /* Pass count used in condition */    int (*Cfptr)();     /* Function pointer used in condition */    ushort  Action;     /* Action to be taken */    ushort  Avar;       /* Variable upon which action is taken */    ulong   Aconst;     /* Constant used in action */    int idx;            /* index into attbl[] */} attbl[ATLISTSIZE];/* At(): *  Command line syntax... *  at address action           # ata *  at address ?condition action        # atca */intAt(int argc,char *argv[]){    int opt, i;    while((opt = getopt(argc,argv,"Dd:f:Ilirs:v:")) != -1) {        switch(opt) {        case 'D':            atdelete(-1);            break;        case 'd':            atdelete(atoi(optarg));            break;        case 'f':            atflagset(optarg);            break;        case 'I':            atinit();            break;        case 'i':            installatpoints();            break;        case 'l':            atlist(1);            break;        case 'r':            removeatpoints();            break;        case 's':            atswap(optarg);            break;        case 'v':            atvarset(optarg);            break;        default:            return(CMD_PARAM_ERROR);        }    }    /* If any options were specified, then return now. */    if (optind != 1)        return(CMD_SUCCESS);    /* If no args, then display 'at' data. */    if (argc == 1) {        atlist(0);        return(CMD_SUCCESS);    }    /* Find an available slot in the atlist table: */    for(i=0;i<ATLISTSIZE;i++) {        if (attbl[i].inuse == 0)            break;    }    if (i == ATLISTSIZE) {        printf("At-table full\n");        return(CMD_FAILURE);    }    /* Load the address: */    attbl[i].address = strtol(argv[optind],(char **)0,0);    /* Establish the action: */    if (setupaction(&attbl[i],argc,argv) == -1) {        printf("Syntax error in action\n");        return(CMD_PARAM_ERROR);    }    /* Establish the condition (if any): */    if (setupcondition(&attbl[i],argc,argv) == -1) {        printf("Syntax error in condition\n");        return(CMD_PARAM_ERROR);    }    /* Copy the original text: */    attbl[i].origtext = *(ushort *)(attbl[i].address);    /* Mark the 'at' entry as in use: */    attbl[i].inuse = 1;    return(CMD_SUCCESS);}/* setupaction(): *  Based on the incoming args, build the action.  *  The action will always be the last argument. */intsetupaction(struct atstruct *atp,int argc,char *argv[]){    char    *action, *cp;    action = argv[argc-1];    cp = action;    while(*cp)        toupper(*cp++);    if (action[0] == '%') {        atp->Avar = strtol(&action[1],&cp,0);        if (!strcmp(cp,"++"))            atp->Action = VAR_INC;        else if (!strcmp(cp,"--"))            atp->Action = VAR_DEC;        else if (*cp == '=') {            atp->Action = VAR_EQ;            atp->Aconst = strtol(cp+1,(char **)0,0);        }        else            return(-1);    }    else if (!strncmp(action,"FSET",4)) {        atp->Action = FLG_SET;        atp->Aconst = strtol(&action[4],(char **)0,0);    }    else if (!strncmp(action,"FCLR",4)) {        atp->Aconst = strtol(&action[4],(char **)0,0);        atp->Action = FLG_CLR;    }    else if (!strncmp(action,"FEQU",4)) {        atp->Aconst = strtol(&action[4],(char **)0,0);        atp->Action = FLG_EQ;    }    else if (!strcmp(action,"BREAK")) {        atp->Action = BREAK;    }    else        return(-1);    return(0);}/* setupcondition(): *  Based on the incoming args, build the condition. *  The condition (if any) will always be the next-to-last argument *  and will be preceded by a question mark. */intsetupcondition(struct atstruct *atp,int argc,char *argv[]){    char    *condition, *cp, *op;    int i;    condition = (char *)0;    for(i=0;i<argc;i++) {        if (!strcmp(argv[i],"if")) {            condition = argv[i+1];            break;        }    }    cp = condition;    while(*cp)        toupper(*cp++);    if (!condition) /* There may not be a condition specified. */        return(0);    op = strchr(condition,'(');    atp->Csize = 1;    if (condition[0] == '%') {        atp->Cvar = strtol(&condition[1],&cp,0);        if (*cp == '.')            atp->Csize = strtol(cp+1,&cp,0);        if (!strncmp(cp,"==",2)) {            atp->Condition = VAR_EQ_CONST;            atp->Cconst = strtol(cp+2,(char **)0,0);        }        else if (!strcmp(cp,"==*")) {            atp->Condition = VAR_EQ_LOC;            atp->Cconst = strtol(cp+3,(char **)0,0);        }        else            return(-1);    }    else if (!strncmp(condition,"FALL",4)) {        atp->Condition = FLG_ALL_SET;        atp->Aconst = strtol(&condition[4],(char **)0,0);    }    else if (!strncmp(condition,"FANY",4)) {        atp->Condition = FLG_ANY_SET;        atp->Cconst = strtol(&condition[4],(char **)0,0);    }    else if (!strncmp(condition,"FEQU",4)) {        atp->Condition = FLG_EQ_CONST;        atp->Cconst = strtol(&condition[4],(char **)0,0);    }    else if (!strncmp(condition,"PCNT==",6)) {        atp->Condition = PASS_COUNT;        atp->Cconst = strtol(&condition[6],(char **)0,0);        atp->Cpcnt = 0;    }    else if (strncmp(op,"()==",4) == 0) {        atp->Condition = FUNC_CALL;        atp->Cfptr = (int(*)())strtol(condition,(char **)0,0);        atp->Cconst = strtol(op+4,(char **)0,0);    }    else        return(-1);    return(0);}intatvarset(char *vset){    int vnum, val;    char    *cp;    vnum = strtol(vset,&cp,0);    if ((vnum < 0) || (vnum >= ATVARTOT)) {        printf("Variable number (%d) out of range\n",vnum);        return(-1);    }    if (*cp != '=') {        printf("Variable set syntax error\n");        return(-1);    }    cp++;    val = strtol(cp,(char **)0,0);    atvars[vnum] = val;    return(0);}intatflagset(char *fset){    atflag = strtol(fset,(char **)0,0);    return(0);}char *AtHelp[] = {    "Complex breakpoints",    "-[Dd:f:Iilrs:v:] {address} [if condition] {action}",    " -D        delete all",    " -d{#}     delete specific",    " -f{xx}    set atflag to 'xx'",    " -I        initialize 'at' structures",    " -i        install atpoints",    " -l        list current state",    " -r        remove atpoints",    " -s{x,y}   swap at 'x' with at 'y'",    " -v{xx=yy} set atvar 'xx' to 'yy'",    "Conditions:",    " %VV==##      atvar 'VV' == '##'",    " PCNT==##     pass count == '##'",    " 0xFFF()==##  func at 0xFFF == '##'",    " FEQUXX       atflag equals 'XX'",    " FALLXX       atflag OR 'XX' equals 'XX'",    " FANYXX       atflag OR 'XX' is non-zero",    " %VV[.s]==*YY atvar 'VV' (size 's') equals *'YY'",    "Actions:",    " %VV=YY   set atvar 'VV' to 'YY'",    " %VV++    increment atvar 'VV'",    " %VV--    decrement atvar 'VV'",    " FEQUXX   set atflag to 'XX'",    " FSETXX   OR 'XX' with atflag",    " FCLRXX   AND ~'XX' with atflag",    " BREAK    break to monitor",    "",    "%VV ranges from %01 through %08",    (char *)0,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -