1
0
Files
irix-657m-src/stand/arcs/ide/common/ide_main.c
2022-09-29 17:59:04 +03:00

305 lines
7.2 KiB
C

/*
* Interactive Diagnostic Environment Command Line Interpreter
*
*/
#ident "$Revision: 1.41 $"
#include <sys/sbd.h>
#include <genpda.h>
#include <parser.h>
#include <libsc.h>
#include <libsk.h>
#include <uif.h>
#include "ide.h"
#include "ide_mp.h"
#include <ide_msg.h>
/*
* intr_jump is the the setjmp buffer used to store the state
* and address to which we return when an interrupt is issued
* from the keyboard. Therefore, only the process controlling
* the duart (the ide_master) ever uses this jumpbuffer, so
* it needn't be in ide's pda.
*/
jmp_buf intr_jump;
/*
* genpda.h evaluates MULTIPROCESSOR; ensure it's been included
*/
#ifndef __GENPDA_H__
dontcompile("#include ERROR, ide_main.c: genpda.h hasn't been included!")
#endif
/*
* ide provides diagnostics with the ability to migrate the master
* thread of execution (i.e. script-interpretation) to another
* processor. The previous master saves its state, signals the
* selected slave, and longjmps back to wait in slave mode, where
* one of three events may awaken it: a) orders from the master to
* launch a procedure, b) exchange-mode orders from master, or
* c) interrupts, if system errors have been directed to that
* processor via software control. Slaves and master both execute
* the same fault-handling code, necessitating arrays of pdas,
* each of which contains a complete set of the required global
* state values.
*/
#if defined(MULTIPROCESSOR)
jmp_buf swap_mode;
#endif
int goteof = 0;
extern char yyinbuff[];
extern size_t yyinlen;
extern int yyinbp;
extern char ide_startup[];
extern int inloop; /* semantic feedback: the parser is inside a loop */
extern int inblock; /* ditto for block {} */
extern int inswitch; /* ditto for switch */
extern int inif; /* ditto for if */
extern int ide_dosource;
extern int _dcache_size;
extern char *ide_version;
extern struct reg_desc sr_desc[], config_desc[];
extern int inif,inrawcmd,inblock,inswitch,inloop,badflag;
char *ide_pstartup = ide_startup;
char *ide_sname;
int ide_cancelstartup;
int _Verbose=0;
int _Debug=0;
#ifdef IP32
extern void config_cache(void );
int ntlbentries;
#endif
static void intr_handler (void);
main(int argc, char *argv[])
{
char cbuf[2*MAXLINELEN];
int jmpval;
ASSERT(!_ide_initialized);
set_sr(IDE_MASTER_SR);
#ifdef IP32 /* used to be R10K and R4K */
{
int r5000 = ((get_prid()&C0_IMPMASK)>>C0_IMPSHIFT) == C0_IMP_R5000;
if (!r5000) {
ntlbentries = R10K_NTLBENTRIES;
} else {
ntlbentries = R4K_NTLBENTRIES;
}
}
config_cache();
cache_K0(); /* make sure K0 runs cached */
#endif /* IP32 */
#ifdef ARG_DEBUG
if (argc && _SHOWIT(VRB)) {
int i;
printf(" IDE main(), argc %d:\n ", argc);
_dump_argvs(argc, argv);
for (i = 0; i < argc; i++)
printf("%d: \"%s\"%s",i,(_STRPTR(argv[i])?argv[i]:"BADARG"),
(i & 0x1 ? "\n " : " "));
printf("\n");
}
#endif
if ( getenv("VERBOSE") ) {
atob(getenv("VERBOSE"), &_Verbose);
msg_printf(INFO,
"\n< Verbose environment (%d==0x%x) initialized from env>\n",
_Verbose, _Verbose);
}
if ( getenv("DEBUG") ) {
atob(getenv("DEBUG"), &_Debug); /* initialize debugging flags */
msg_printf(INFO,
"\n< Debug settings (%d==0x%x) initialized from env>\n",
_Debug, _Debug);
}
ide_mpsetup(); /* set up ide's pdas */
(void)version ();
ide_init(argc, argv);
/* buffoff(); */
#ifdef _STANDALONE
/* trap ^C plus <esc> on field */
if (strstr(ide_version,"field")) {
Signal(SIGHUP,SIGDefault);
(void)ioctl(0,TIOCINTRCHAR,(long)"\003\033");
}
#endif
if (jmpval = setjmp(intr_jump)) {
msg_printf(SUM, "vid %d, restart", GPME(my_virtid));
if (Reportlevel >= DBG)
msg_printf(SUM,": badflag was %s\n",(badflag?"SET":"CLEAR"));
ide_whoami(cbuf);
switch(jmpval) {
case SCRIPT_ERR_RESTART:
msg_printf(INFO,
"%s, restart: remainder of script was skipped\n", cbuf);
break;
case MASTER_INT_RESTART:
msg_printf(INFO, "%s: restart due to interrupt\n", cbuf);
break;
case SLAVE_INT_RESTART:
msg_printf(IDE_ERR,
"%s: slave (v%d,pidx%d) is executing master code!!\n",
cbuf, cpuid(), GPME(my_physid));
break;
default:
msg_printf(IDE_ERR, "%s: unknown longjmp returnval %d\n",
cbuf, jmpval);
break;
}
busy (0);
}
Signal(SIGINT, intr_handler);
#ifdef _STANDALONE
_hook_exceptions();
#endif
while ( ! goteof )
yyparse();
msg_printf(JUST_DOIT,"!!! fell through in main\n");
putchar('\n');
EnterInteractiveMode();
/*NOTREACHED*/
}
static void
intr_handler (void)
{
int vid_me = cpuid();
msg_printf(SUM, "\nInterrupt: ");
ide_whoami(NULL);
msg_printf(SUM, "\n");
ide_cancelstartup = 1;
yyinlen = 0;
handle_interrupt();
Signal (SIGALRM, SIGIgnore);
/*
* make damn sure nothing fishy's goin' on around here...
*/
if ((IDE_ME(ide_mode)!=IDE_MASTER && _ide_info.master_vid==vid_me) ||
(IDE_ME(ide_mode)==IDE_MASTER && _ide_info.master_vid!=vid_me)) {
msg_printf(IDE_ERR,
"!!intr_handler(v%d): ide_info disagreement!\n", vid_me);
msg_printf(JUST_DOIT, " my mode %d, NOT master (%d): ",
IDE_ME(ide_mode), IDE_MASTER);
msg_printf(JUST_DOIT, " vid %d is master!\n",
_ide_info.master_vid);
ide_panic("intr_handler");
}
if (IDE_ME(ide_mode)!=IDE_MASTER || _ide_info.master_vid!=vid_me) {
ASSERT(IDE_ME(ide_mode) == IDE_SLAVE);
msg_printf(DBG,
" intr_hand(vid %d): my mode %d, master's vid is %d\n",
vid_me, IDE_ME(ide_mode), _ide_info.master_vid);
msg_printf(DBG, " longjmp back to slave_buf addr 0x%x: ",
(IDE_ME(slave_jbuf)));
longjmp(IDE_ME(slave_jbuf), SLAVE_INT_RESTART);
}
longjmp (intr_jump, MASTER_INT_RESTART);
/*NOTREACHED*/
} /* intr_handler */
int
version (void)
{
msg_printf(JUST_DOIT,"%s\n\n",ide_version);
return 0;
}
/*
* Get input from somewhere
*
* ide supports three different types of input:
* 1. From a startup script linked in at compile time
* 2. From the keyboard
* 3. From a remote device via the "source" command
*
*/
int
ide_refill(void)
{
static struct edit_linebuf elinebuf;
char *tmpp;
if ( !ide_cancelstartup && *ide_pstartup ) {
ide_sname = "startup script";
if ( (yyinlen = strlen(ide_pstartup)) >= MAXLINELEN )
strncpy(yyinbuff,ide_pstartup, yyinlen = MAXLINELEN-1 );
else
strcpy( yyinbuff, ide_pstartup );
ide_pstartup += yyinlen;
} else {
if ( !(ide_dosource && (yyinlen = getsfromsource(yyinbuff))) ) {
ide_sname = 0;
if ( inloop || inswitch || inblock || inif ) {
sym_t *psym = findsym("PS2");
if ( psym )
ide_puts(psym->sym_s);
else
ide_puts("> ");
} else {
sym_t *psym = findsym("PS1");
if ( psym )
ide_puts(psym->sym_s);
else
ide_puts("! ");
}
/* Interface from edit_gets() to yyinbuff is
* sub-optimal, and sizeof(yyinbuff) > LINESIZE.
*/
tmpp = edit_gets(&elinebuf);
if (!tmpp) return EOF;
strncpy(yyinbuff,tmpp,LINESIZE);
yyinlen = strlen(yyinbuff);
yyinbuff[yyinlen++] = '\n';
}
}
yyinbp = 0;
yyinbuff[yyinlen] = '\0';
return yyinbuff[yyinbp++];
}
#if !EVEREST
/* stubs to keep some some textport data out of ide */
unsigned char clogo_data[1];
int clogo_w, clogo_h;
#endif