📄 main.c
字号:
/* $Id: main.c,v 1.22 2003/08/30 14:55:57 pefo Exp $ *//* * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com) * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Opsycon AB, Sweden. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This code was created from code released to Public Domain * by LSI Logic and Algorithmics UK. */ #include <stdio.h>#include <termio.h>#include <endian.h>#include <string.h>#include <signal.h>#include <setjmp.h>#include <ctype.h>#include <unistd.h>#include <stdlib.h>#ifdef _KERNEL#undef _KERNEL#include <sys/ioctl.h>#define _KERNEL#else#include <sys/ioctl.h>#endif#include <pmon.h>#include <exec.h>#include <file.h>#include "mod_debugger.h"#include "mod_symbols.h"#include "sd.h"#include "wd.h"extern void *callvec;#include "cmd_hist.h" /* Test if command history selected */#include "cmd_more.h" /* Test if more command is selected */jmp_buf jmpb; /* non-local goto jump buffer */char line[LINESZ + 1]; /* input line */struct termio clntterm; /* client terminal mode */struct termio consterm; /* console terminal mode */register_t initial_sr;char prnbuf[LINESZ + 8]; /* commonly used print buffer */int repeating_cmd;unsigned int moresz = 10;static void autorun(char *);extern void __init(void);extern void _exit (int retval);extern void delay(int);#ifdef INETstatic voidpmon_intr (int dummy){ sigsetmask (0); longjmp (jmpb, 1);}#endifFILE *logfp = stdout; #if NCMD_HIST == 0voidget_line(char *line, int how){ int i; i = read (STDIN, line, LINESZ); if(i > 0) { i--; } line[i] = '\0';}#endif/* * Main interactive command loop * ----------------------------- * * Clean up removing breakpoints etc and enter main command loop. * Read commands from the keyboard and execute. When executing a * command this is where <crtl-c> takes us back. */intpmon_main(){ char prompt[32]; if (setjmp(jmpb)) { /* Bailing out, restore */ closelst(0); ioctl(STDIN, TCSETAF, &consterm); printf(" break!\r\n"); }#ifdef INET signal (SIGINT, pmon_intr);#else ioctl (STDIN, SETINTR, jmpb);#endif#if NMOD_DEBUGGER > 0 rm_bpts();#endif md_setsr(NULL, initial_sr); /* XXX does this belong here? */ while(1) { strncpy (prompt, getenv ("prompt"), sizeof(prompt));#if NCMD_HIST > 0 if (strchr(prompt, '!') != 0) { char tmp[8], *p; p = strchr(prompt, '!'); strdchr(p); /* delete the bang */ sprintf(tmp, "%d", histno); stristr(p, tmp); }#endif printf("%s", prompt);#if NCMD_HIST > 0 get_cmd(line);#else get_line(line, 0);#endif do_cmd(line); console_state(1); } return(0);}/* * Handle autoboot execution * ------------------------- * * Autoboot variable set. Countdown bootdelay to allow manual * intervention. If CR is pressed skip counting. If var bootdelay * is set use the value othervise default to 15 seconds. */static voidautorun(char *s){ char buf[LINESZ]; char *d; unsigned int dly, lastt; unsigned int cnt; struct termio sav; if(s != NULL && strlen(s) != 0) { d = getenv ("bootdelay"); if(!d || !atob (&dly, d, 10) || dly < 0 || dly > 99) { dly = 15; } SBD_DISPLAY ("AUTO", CHKPNT_AUTO); printf("Autoboot command: \"%.60s\"\n", s); printf("Press <Enter> to execute or any other key to abort.\n"); ioctl (STDIN, CBREAK, &sav); lastt = 0; dly++; do {#if defined(HAVE_TOD) && defined(DELAY_INACURATE) time_t t; t = tgt_gettime (); if(t != lastt) { printf ("\r%2d", --dly); lastt = t; }#else delay(1000000); printf ("\r%2d", --dly);#endif ioctl (STDIN, FIONREAD, &cnt); } while (dly != 0 && cnt == 0); if(cnt > 0 && strchr("\n\r", getchar())) { cnt = 0; } ioctl (STDIN, TCSETAF, &sav); putchar ('\n'); if(cnt == 0) { strcpy (buf, s); do_cmd (buf); } }}/* * PMON2000 entrypoint. Called after initial setup. */voiddbginit (char *adr){ int memsize, freq; char fs[10], *fp; char *s;/* splhigh();*/ memsize = totalmemsize; if (!kmemtop) kmemtop = (void *)memsize; __init(); /* Do all constructor initialisation */ SBD_DISPLAY ("ENVI", CHKPNT_ENVI); envinit ();#if defined(SMP) /* Turn on caches unless opted out */ if (!getenv("nocache")) md_cacheon();#endif SBD_DISPLAY ("SBDD", CHKPNT_SBDD); tgt_devinit();#ifdef INET SBD_DISPLAY ("NETI", CHKPNT_NETI); init_net (1);#endif#if NCMD_HIST > 0 SBD_DISPLAY ("HSTI", CHKPNT_HSTI); histinit ();#endif#if NMOD_SYMBOLS > 0 SBD_DISPLAY ("SYMI", CHKPNT_SYMI); syminit ();#endif#ifdef DEMO SBD_DISPLAY ("DEMO", CHKPNT_DEMO); demoinit ();#endif SBD_DISPLAY ("SBDE", CHKPNT_SBDE); initial_sr |= tgt_enable (tgt_getmachtype ());#ifdef SR_FR Status = initial_sr & ~SR_FR; /* don't confuse naive clients */#endif /* Set up initial console terminal state */ ioctl(STDIN, TCGETA, &consterm); tgt_logo(); printf ("\nConfiguration [%s,%s", TARGETNAME, BYTE_ORDER == BIG_ENDIAN ? "EB" : "EL");#ifdef SMP printf (",SMP");#endif#ifdef INET printf (",NET");#endif#if NSD > 0 printf (",SCSI");#endif#if NWD > 0 printf (",IDE");#endif printf ("]\nVersion: %s.\n", vers); printf ("Supported loaders [%s]\n", getExecString()); printf ("Supported filesystems [%s]\n", getFSString()); printf ("This software may be redistributed under the BSD copyright.\n"); tgt_machprint(); freq = tgt_pipefreq (); sprintf(fs, "%d", freq); fp = fs + strlen(fs) - 6; fp[3] = '\0'; fp[2] = fp[1]; fp[1] = fp[0]; fp[0] = '.'; printf (" %s MHz", fs); freq = tgt_cpufreq (); sprintf(fs, "%d", freq); fp = fs + strlen(fs) - 6; fp[3] = '\0'; fp[2] = fp[1]; fp[1] = fp[0]; fp[0] = '.'; printf (" / Bus @ %s MHz\n", fs); printf ("Memory size %3d MB.\n", memsize / (1024 * 1024)); tgt_memprint();#if defined(SMP) tgt_smpstartup();#endif printf ("\n"); md_clreg(NULL); md_setpc(NULL, (int32_t) CLIENTPC); md_setsp(NULL, tgt_clienttos ()); s = getenv ("autoboot"); autorun (s);}/* * closelst(lst) -- Handle client state opens and terminal state. */voidcloselst(int lst){ switch (lst) { case 0: /* XXX Close all LU's opened by client */ break; case 1: break; case 2: /* reset client terminal state to consterm value */ clntterm = consterm; break; }}/* * console_state(lst) -- switches between PMON2000 and client tty setting. */voidconsole_state(int lst){ switch (lst) { case 1: /* save client terminal state and set PMON default */ ioctl (STDIN, TCGETA, &clntterm); ioctl (STDIN, TCSETAW, &consterm); break; case 2: /* restore client terminal state */ ioctl (STDIN, TCSETAF, &clntterm); break; }}/************************************************************* * dotik(rate,use_ret) */voiddotik (rate, use_ret) int rate, use_ret;{static int tik_cnt;static const char more_tiks[] = "|/-\\";static const char *more_tik; tik_cnt -= rate; if (tik_cnt > 0) { return; } tik_cnt = 256000; if (more_tik == 0) { more_tik = more_tiks; } if (*more_tik == 0) { more_tik = more_tiks; } if (use_ret) { printf (" %c\r", *more_tik); } else { printf ("\b%c", *more_tik); } more_tik++;}#if NCMD_MORE == 0/* * Allow usage of more printout even if more is not compiled in. */intmore (p, cnt, size) char *p; int *cnt, size;{ printf("%s\n", p); return(0);}#endif/* * Non direct command placeholder. Give info to user. */int no_cmd(ac, av) int ac; char *av[];{ printf("Not a direct command! Use 'h %s' for more information.\n", av[0]); return (1);}/* * Build argument area on 'clientstack' and set up clients * argument registers in preparation for 'launch'. * arg1 = argc, arg2 = argv, arg3 = envp, arg4 = callvector */voidinitstack (ac, av, addenv) int ac; char **av; int addenv;{ char **vsp, *ssp; int ec, stringlen, vectorlen, stacklen, i; register_t nsp; /* * Calculate the amount of stack space needed to build args. */ stringlen = 0; for (i = 0; i < ac; i++) { stringlen += strlen(av[i]) + 1; } if (addenv) { envsize (&ec, &stringlen); } else { ec = 0; } stringlen = (stringlen + 3) & ~3; /* Round to words */ vectorlen = (ac + ec + 2) * sizeof (char *); stacklen = ((vectorlen + stringlen) + 7) & ~7; /* * Allocate stack and us md code to set args. */ nsp = md_adjstack(NULL, 0) - stacklen; md_setargs(NULL, ac, nsp, nsp + (ac + 1) * sizeof(char *), (int)callvec); /* put $sp below vectors, leaving 32 byte argsave */ md_adjstack(NULL, nsp - 32); memset((void *)((int)nsp - 32), 0, 32); /* * Build argument vector and strings on stack. * Vectors start at nsp; strings after vectors. */ vsp = (char **)(int)nsp; ssp = (char *)((int)nsp + vectorlen); for (i = 0; i < ac; i++) { *vsp++ = ssp; strcpy (ssp, av[i]); ssp += strlen(av[i]) + 1; } *vsp++ = (char *)0; /* build environment vector on stack */ if (ec) { envbuild (vsp, ssp); } else { *vsp++ = (char *)0; } /* * Finally set the link register to catch returning programs. */ md_setlr(NULL, (register_t)_exit);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -