www.pudn.com > tfs.rar > go.c


/* go.c:
 *  This code is part of the DEBUG code that allows the monitor to do
 *  some basic debug stuff (go,resume, set breakpoints, etc...).
 *
 *  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 "cpuio.h"
//#include "cpu.h"
#include "genlib.h"
#include "stddefs.h"
//#include "cli.h"
#define BAILOUT     (7<<4)
#define INITIALIZE  (3<<4)
#define sizeof  (int)sizeof

char    *ArgvAry[32];   /* Used for passing args to application */


/* Go():
 *  Run or resume downloaded application.
 *
 *  Arguments...
 *  If no args, do a resume based on stored pc.
 *
 *  arg1:       address.
 *  arg2-argN:  args passed to function at address "arg1"
 */

#if INCLUDE_DEBUG

char *GoHelp[] = {
    "Execute/resume downloaded application",
    "-[p:Rr:s:u:] [addr]",
    " -p {PC}  set PC value",
    " -R       dump regs",
    " -r {SR}  set SR reg",
    " -s {SSP} set SSP reg",
    " -u {USP} set USP reg",
    0,
};

int
Go(int argc,char *argv[])
{
    void    bailout();
    extern  ulong   PCatBreak;
    ulong   ss, us, pc, sr, reg;
    int opt, ssset, usset, srset, pcset, regdisp;

    srset = ssset = usset = pcset = 0;
    regdisp = 0;
    while((opt=getopt(argc,argv,"Rp:r:s:u:")) != -1) {
        switch(opt) {
        case 'p':
            pc = (ushort)strtol(optarg,(char **)0,0);
            pcset = 1;
            break;
        case 'R':
            regdisp = 1;
            break;
        case 'r':
            sr = (ushort)strtol(optarg,(char **)0,0);
            srset = 1;
            break;
        case 's':
            ss = (ulong)strtol(optarg,(char **)0,0);
            ssset = 1;
            break;
        case 'u':
            us = (ulong)strtol(&optarg[1],(char **)0,0);
            usset = 1;
            break;
        default:
            return(CMD_PARAM_ERROR);
        }
    }
    if (argc > optind) {
        reg = strtol(argv[optind],(char **)0,0);
        putreg("PC",reg);
        if (!srset) {
            sr = MONITOR_STATUS;
            srset = 1;
        }
        if (!ssset) {
            ss = SUPERVISOR_STACK;
            ssset = 1;
        }
        if (!usset) {
            us = USER_STACK;
            usset = 1;
        }
        *(ulong *)(ss+6) = (ulong)bailout;
        installatpoints();
    }
    else if (StateOfMonitor == BREAKPOINT) {
        getreg("PC",®);
        if (PCatBreak == reg)
            setTraceBit();
            else
            installatpoints();
    }
    if (srset)
        putreg("SR",sr);
    if (ssset)
        putreg("SS",ss);
    if (usset)
        putreg("US",us);
    if (pcset)
        putreg("PC",pc);

    if (regdisp)
        showregs();

#if INCLUDE_ETHERNET
    DisableEthernet();
#endif
    EnableBreakInterrupt();
    resume();
    return(CMD_SUCCESS);    /* should not get here */
}
#endif

void
bailout()
{
    puts("Program terminated\n");
#if INCLUDE_DEBUG
    removeatpoints();
#endif
    monrestart(BAILOUT);
}

/* Call():
 *  This function is called when the user wants to execute an 
 *  embedded function. 
 *  The the argument is preceded by an ampersand, then a pointer
 *  to the argument is passed to the function instead of a 
 *  strtol() conversion.
 */
char *CallHelp[] = {
    "Call embedded function",
    "-[aqv:] {address} [arg1] [arg2] ...",
    " -a       pass (argc,argv) function",
    " -q       quiet mode",
    " -v {var} put return val in varname",
    0,
};

int
Call(int argc,char *argv[])
{
    char    *varname;
    long    args[10];
    int     i, j, ret, opt, useargc, quiet;
    int     (*func)();

    quiet = 0;
    useargc = 0;
    varname = (char *)0;
    while((opt=getopt(argc,argv,"aqv:")) != -1) {
        switch(opt) {
        case 'a':
            useargc = 1;
            break;
        case 'q':
            quiet = 1;
            break;
        case 'v':
            varname = optarg;
            break;
        default:
            return(CMD_PARAM_ERROR);
        }
    }

    if ((argc < optind+1) || (argc > optind+11))
        return(CMD_PARAM_ERROR);

    func = (int(*)())strtol(argv[optind],(char **)0,0);

    /* If useargc flag is not set, then retrieve and convert
     * args from command line.  If the first character of the
     * argument is an ampersand (&), then a pointer to the argument
     * is passed; otherwise, the argument is converted to a long
     * integer using strtol()...
     */
    if (!useargc) {
        for(j=0,i=optind+1;i= (sizeof(ArgvAry)/sizeof(char *)))
        return(-1);

    ArgvAry[argnum] = argptr;
    return(0);
}

/* getargv():
 *  Provides a hook allowing the downloaded application code to 
 *  handle main(argc,argv) in a painless way.  The Argv[] array
 *  location is returned by get_argv() and is assumed to contain
 *  the NULL terminated list of argv pointers...  Immediately
 *  after the NULL termination is the data that the argv pointers
 *  are referencing.  
 *  This provides a total of 64*4 bytes of space to accomodate
 *  the needs of argv.
 */

void
getargv(int *argc,char ***argv)
{
    int i;

    if (argv)
        *argv = &ArgvAry[0];
    for(i=0;;i++)
        if (ArgvAry[i] == 0)
            break;
    if (argc)
        *argc = i;
}
#else
void
getargv(int *argc,char ***argv)
{
    if (argc)
        *argc = -1;
}
#endif