Line 25... |
Line 25... |
#include <string.h>
|
#include <string.h>
|
#include <stdlib.h>
|
#include <stdlib.h>
|
#include <signal.h>
|
#include <signal.h>
|
#include <stdarg.h>
|
#include <stdarg.h>
|
|
|
|
#include <readline/readline.h>
|
|
#include <readline/history.h>
|
|
|
#include "arch.h"
|
#include "arch.h"
|
#include "parse.h"
|
#include "parse.h"
|
#include "abstract.h"
|
#include "abstract.h"
|
#include "trace.h"
|
#include "trace.h"
|
#include "execute.h"
|
#include "execute.h"
|
|
|
/* CVS revision number. */
|
/* CVS revision number. */
|
static const char rcsrev[] = "$Revision: 1.2 $";
|
static const char rcsrev[] = "$Revision: 1.3 $";
|
|
|
/* Continuos run versus single step tracing switch. */
|
/* Continuos run versus single step tracing switch. */
|
int cont_run;
|
int cont_run;
|
|
|
/* History of execution */
|
/* History of execution */
|
int histexec[HISTEXEC_LEN];
|
int histexec[HISTEXEC_LEN];
|
|
|
|
|
|
char *sim_commands [] = {
|
|
"q",
|
|
"t",
|
|
"help",
|
|
"dm",
|
|
"run",
|
|
"pr",
|
|
"pm",
|
|
"pc",
|
|
"brk",
|
|
"hist",
|
|
"stats",
|
|
"info",
|
|
"r",
|
|
0
|
|
};
|
|
|
void debug(const char *format, ...)
|
void debug(const char *format, ...)
|
{
|
{
|
#if DEBUG
|
#if DEBUG
|
char *p;
|
char *p;
|
va_list ap;
|
va_list ap;
|
Line 58... |
Line 79... |
free(p);
|
free(p);
|
#endif
|
#endif
|
return;
|
return;
|
}
|
}
|
|
|
void ctrl_c(int signum)
|
void
|
|
ctrl_c(signum)
|
|
int signum;
|
{
|
{
|
cont_run = 1;
|
cont_run = 1;
|
signal(SIGINT, ctrl_c);
|
signal(SIGINT, ctrl_c);
|
}
|
}
|
|
|
void version()
|
void
|
|
version()
|
{
|
{
|
printf("\n");
|
printf("\n");
|
printf("OpenRISC 1000 Architectural Simulator, revision %s\n", rcsrev);
|
printf("OpenRISC 1000 Architectural Simulator, revision %s\n", rcsrev);
|
printf("Copyright (C) 1999 Damjan Lampret, lampret@opencores.org\n");
|
printf("Copyright (C) 1999 Damjan Lampret, lampret@opencores.org\n");
|
printf("Visit http://www.opencores.org for more information about ");
|
printf("Visit http://www.opencores.org for more information about ");
|
Line 77... |
Line 101... |
printf("details see COPYING.\nThis is free software, and you ");
|
printf("details see COPYING.\nThis is free software, and you ");
|
printf("are welcome to redistribute it under certain\nconditions; ");
|
printf("are welcome to redistribute it under certain\nconditions; ");
|
printf("for details see COPYING.\n");
|
printf("for details see COPYING.\n");
|
}
|
}
|
|
|
void help()
|
void
|
|
help()
|
{
|
{
|
printf("q - quit simulator\n");
|
printf("q - quit simulator\n");
|
printf("r - display all registers\n");
|
printf("r - display all registers\n");
|
printf("t - execute next instruction\n");
|
printf("t - execute next instruction\n");
|
printf("run <cycles> [<hush>] - execute <cycles> instructions, no reg dump if hush\n");
|
printf("run <cycles> [<hush>] - execute <cycles> instructions, no reg dump if hush\n");
|
Line 95... |
Line 120... |
printf("info - configuration info (caches etc.)\n");
|
printf("info - configuration info (caches etc.)\n");
|
printf("<cmd> > <filename> - redirect simulator stdout to <filename> (and not emulated printf)\n");
|
printf("<cmd> > <filename> - redirect simulator stdout to <filename> (and not emulated printf)\n");
|
printf("help - available commands (this list)\n");
|
printf("help - available commands (this list)\n");
|
}
|
}
|
|
|
int main(int argc, char *argv[])
|
main(argc, argv)
|
|
int argc;
|
|
char *argv[];
|
{
|
{
|
char linestr[500];
|
char *linestr;
|
char item1[500];
|
char item1[500];
|
char *redirstr;
|
char *redirstr;
|
int hush;
|
int hush;
|
|
|
if (argc != 2) {
|
if (argc != 2)
|
|
{
|
printf("Usage: %s <filename>\n", argv[0]);
|
printf("Usage: %s <filename>\n", argv[0]);
|
exit(-1);
|
exit(-1);
|
}
|
}
|
|
|
|
initialize_readline (); /* Bind our completer. */
|
|
|
version();
|
version();
|
init_defconfig();
|
init_defconfig();
|
signal(SIGINT, ctrl_c);
|
signal(SIGINT, ctrl_c);
|
initstats();
|
initstats();
|
loadcode(argv[1]);
|
loadcode(argv[1]);
|
reset();
|
reset();
|
while(1) {
|
|
printf("\n# ");
|
|
fgets(linestr, sizeof(linestr), stdin);
|
|
|
|
if (redirstr = strstr(linestr, ">")) {
|
while(1)
|
|
{
|
|
linestr = readline("(sim) ");
|
|
|
|
if (!linestr)
|
|
{
|
|
break;
|
|
}
|
|
linestr = stripwhite (linestr);
|
|
|
|
if (strlen(linestr) == 0)
|
|
{
|
|
char *l = repeat_last_command ();
|
|
|
|
if (l)
|
|
{
|
|
free (linestr);
|
|
linestr = l;
|
|
}
|
|
}
|
|
|
|
if (*linestr)
|
|
{
|
|
add_history (linestr);
|
|
}
|
|
|
|
if (redirstr = strstr(linestr, ">"))
|
|
{
|
*redirstr = '\0';
|
*redirstr = '\0';
|
strtoken(&redirstr[1], item1, 1);
|
strtoken(&redirstr[1], item1, 1);
|
freopen(item1, "w+", stdout);
|
freopen(item1, "w+", stdout);
|
}
|
}
|
|
|
Line 151... |
Line 205... |
to = from + 0x40;
|
to = from + 0x40;
|
}
|
}
|
if (strlen(item3))
|
if (strlen(item3))
|
to = strtoul(item3, NULL, 0);
|
to = strtoul(item3, NULL, 0);
|
dumpmemory(from, to);
|
dumpmemory(from, to);
|
|
printf("\n");
|
} else
|
} else
|
if (strcmp(item1, "pm") == 0) { /* patch memory */
|
if (strcmp(item1, "pm") == 0) { /* patch memory */
|
char item2[20];
|
char item2[20];
|
char item3[20];
|
char item3[20];
|
static int addr = 0;
|
static int addr = 0;
|
Line 180... |
Line 235... |
char item2[20];
|
char item2[20];
|
|
|
strtoken(linestr, item2, 2);
|
strtoken(linestr, item2, 2);
|
pctemp = strtoul(item2, NULL, 0);
|
pctemp = strtoul(item2, NULL, 0);
|
} else
|
} else
|
if (strcmp(item1, "brk") == 0) { /* set/clear breakpoint */
|
if (strcmp(item1, "break") == 0) { /* set/clear breakpoint */
|
char item2[20];
|
char item2[20];
|
|
|
strtoken(linestr, item2, 2);
|
strtoken(linestr, item2, 2);
|
set_insnbrkpoint(strtoul(item2, NULL, 0));
|
set_insnbrkpoint(strtoul(item2, NULL, 0));
|
} else
|
} else
|
Line 224... |
Line 279... |
if (strcmp(item1, "info") == 0) { /* configuration info */
|
if (strcmp(item1, "info") == 0) { /* configuration info */
|
bpb_info();
|
bpb_info();
|
btic_info();
|
btic_info();
|
ic_info();
|
ic_info();
|
dc_info();
|
dc_info();
|
|
} else {
|
|
printf("%s: Unknown command.\n", linestr);
|
}
|
}
|
|
|
while(cont_run) {
|
while(cont_run) {
|
cont_run--;
|
cont_run--;
|
fetch();
|
fetch();
|
Line 239... |
Line 296... |
|
|
hush = 0;
|
hush = 0;
|
fflush(stdout);
|
fflush(stdout);
|
freopen("/dev/fd/0", "w+", stdout);
|
freopen("/dev/fd/0", "w+", stdout);
|
|
|
|
if (linestr)
|
|
free (linestr);
|
|
|
}
|
}
|
exit(0);
|
exit(0);
|
}
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|
|
char *command_generator ();
|
|
char **sim_completion ();
|
|
|
|
/* Tell the GNU readline library how to complete. We want to try to complete
|
|
on command names if this is the first word in the line, or on filenames
|
|
if not. */
|
|
void initialize_readline ()
|
|
{
|
|
/* Allow conditional parsing of the ~/.inputrc file. */
|
|
rl_readline_name = "or1ksim";
|
|
|
|
/* Tell the completer that we want a crack first. */
|
|
rl_attempted_completion_function = (CPPFunction *)sim_completion;
|
|
}
|
|
|
|
/* Attempt to complete on the contents of TEXT. START and END bound the
|
|
region of rl_line_buffer that contains the word to complete. TEXT is
|
|
the word to complete. We can use the entire contents of rl_line_buffer
|
|
in case we want to do some simple parsing. Return the array of matches,
|
|
or NULL if there aren't any. */
|
|
char **
|
|
sim_completion (text, start, end)
|
|
char *text;
|
|
int start, end;
|
|
{
|
|
char **matches;
|
|
|
|
matches = (char **)NULL;
|
|
|
|
/* If this word is at the start of the line, then it is a command
|
|
to complete. Otherwise it is the name of a file in the current
|
|
directory. */
|
|
if (start == 0)
|
|
matches = completion_matches (text, command_generator);
|
|
|
|
return (matches);
|
|
}
|
|
|
|
/* Generator function for command completion. STATE lets us know whether
|
|
to start from scratch; without any state (i.e. STATE == 0), then we
|
|
start at the top of the list. */
|
|
char *
|
|
command_generator (text, state)
|
|
char *text;
|
|
int state;
|
|
{
|
|
static int list_index, len;
|
|
char *name;
|
|
|
|
/* If this is a new word to complete, initialize now. This includes
|
|
saving the length of TEXT for efficiency, and initializing the index
|
|
variable to 0. */
|
|
if (!state)
|
|
{
|
|
list_index = 0;
|
|
len = strlen (text);
|
|
}
|
|
|
|
/* Return the next name which partially matches from the command list. */
|
|
while (name = sim_commands[list_index])
|
|
{
|
|
list_index++;
|
|
|
|
if (strncmp (name, text, len) == 0)
|
|
return (dupstr(name));
|
|
}
|
|
|
|
/* If no names matched, then return NULL. */
|
|
return ((char *)NULL);
|
|
}
|
|
|
|
|
|
/* Strip whitespace from the start and end of STRING. Return a pointer
|
|
into STRING. */
|
|
char *
|
|
stripwhite (string)
|
|
char *string;
|
|
{
|
|
register char *s, *t;
|
|
|
|
for (s = string; whitespace (*s); s++)
|
|
;
|
|
|
|
if (*s == 0)
|
|
return (s);
|
|
|
|
t = s + strlen (s) - 1;
|
|
while (t > s && whitespace (*t))
|
|
t--;
|
|
*++t = '\0';
|
|
|
|
return s;
|
|
}
|
|
|
|
char *
|
|
dupstr (s)
|
|
char *s;
|
|
{
|
|
char *r;
|
|
|
|
r = xmalloc (strlen (s) + 1);
|
|
strcpy (r, s);
|
|
return (r);
|
|
}
|
|
|
|
/* Repeats the last command. */
|
|
char *
|
|
repeat_last_command ()
|
|
{
|
|
int offset = where_history ();
|
|
HIST_ENTRY *hist;
|
|
|
|
if (hist = history_get (offset))
|
|
{
|
|
return dupstr (hist->line);
|
|
}
|
|
return 0;
|
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|