URL
https://opencores.org/ocsvn/or1k_old/or1k_old/trunk
Subversion Repositories or1k_old
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 1352 to Rev 1353
- ↔ Reverse comparison
Rev 1352 → Rev 1353
/trunk/or1ksim/sim-config.h
301,6 → 301,8
int storecycles; |
|
long long reset_cycles; |
|
int hush; /* Is simulator to do reg dumps */ |
} sim; |
|
/* Command line parameters */ |
358,7 → 360,7
void read_script_file (char *filename); |
|
/* Executes set sim command. Returns nonzero if error. */ |
void set_config_command (char *s); |
void set_config_command (int argc, char **argv); |
|
/* Outputs C structure of current config to file */ |
void output_cfg (FILE *f); |
369,4 → 371,11
|
void print_config(); |
|
void sim_done(void); |
|
/* Resets all subunits */ |
void sim_reset(void); |
|
/* Handle the sim commandline */ |
void handle_sim_command(void); |
#endif |
/trunk/or1ksim/cpu/common/parse.h
37,11 → 37,5
/* This function is very similar to strncpy, except it null terminates the string */ |
char *strstrip (char *dst, const char *src, int n); |
|
/* Returns n-th token from string */ |
char *strtoken(char *in, char *out, int which); |
|
/* Parses string line and puts up to maxparam parameters into argv[]; number of parameters is returned */ |
int tokenize_line (char *str, char *argv[], int maxparam); |
|
/* Loads file to memory starting at address startaddr and returns freemem. */ |
unsigned long loadcode(char *filename, oraddr_t startaddr, oraddr_t virtphy_transl); |
/trunk/or1ksim/cpu/common/parse.c
59,29 → 59,6
/* Used to signal whether during loading of programs a translation fault occured. */ |
static unsigned long transl_error; |
|
|
char *strtoken(char *in, char *out, int which) |
{ |
char *super; |
char *sub; |
char *newline; |
|
super = strdup(in); |
sub = strtok(super, " \t"); |
while (sub && --which) |
sub = strtok(NULL, " \t"); |
if (sub && !which) { |
if ((newline = strchr(sub, '\n'))) |
newline[0] = '\0'; |
strcpy(out, sub); |
} else |
out[0] = '\0'; |
free(super); |
if ((newline = strchr(out, '\r'))) /* get rid of CR */ |
newline[0] = '\0'; |
return(out); |
} |
|
char * |
stripwhite (string) |
char *string; |
110,25 → 87,6
return dst; |
} |
|
/* Parses string line and puts up to maxparam parameters into argv[]; number of parameters is returned */ |
int tokenize_line (char *str, char *argv[], int maxparam) |
{ |
int i, param = 0; |
str = stripwhite (str); |
while (*str) { |
char *p; |
argv[param] = str; |
while (*str && !isblank (*str)) str++; |
param++; |
p = str; |
if (param >= maxparam) break; |
while (*str && isblank (*str)) str++; |
*p = 0; |
} |
for (i = 0; i < param; i++) argv[i] = stripwhite (argv[i]); |
return param; |
} |
|
/* Used only by the simulator loader to translate logical addresses into physical. |
If loadcode() is called with valid virtphy_transl pointer to a table of |
translations then translate() performs translation otherwise phy address is |
/trunk/or1ksim/sim-cmd.c
0,0 → 1,674
/* sim-cmd.c -- Simulator command parsing |
Copyright (C) 1999 Damjan Lampret, lampret@opencores.org |
|
|
This file is part of OpenRISC 1000 Architectural Simulator. |
|
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
|
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
|
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ |
|
|
#include <stdio.h> |
#include <string.h> |
#include <ctype.h> |
#include <unistd.h> |
|
#include "config.h" |
|
#ifdef HAVE_LIBREADLINE |
#include <readline/readline.h> |
#include <readline/history.h> |
#endif /* HAVE_LIBREADLINE */ |
|
#ifdef HAVE_INTTYPES_H |
#include <inttypes.h> |
#endif |
|
#include "port.h" |
#include "arch.h" |
#include "abstract.h" |
#include "labels.h" |
#include "opcode/or32.h" |
#include "mprofiler.h" |
#include "profiler.h" |
#include "sim-config.h" |
#include "dumpverilog.h" |
#include "execute.h" |
#include "debug_unit.h" |
#include "debug.h" |
#include "trace.h" |
#include "stats.h" |
#include "cuc.h" |
#include "gdbcomm.h" |
|
/* FIXME: These *really* need to be cleaned up */ |
#include "sprs.h" |
#include "immu.h" |
#include "dmmu.h" |
#include "mc.h" |
#include "icache_model.h" |
#include "dcache_model.h" |
#include "branch_predict.h" |
#include "16450.h" |
#include "dma.h" |
#include "ethernet.h" |
#include "gpio.h" |
#include "atahost.h" |
#include "ps2kbd.h" |
|
extern char *disassembled; |
static void debugmem( oraddr_t from, oraddr_t to ) |
{ |
int i; |
PRINTF("starting to dump mem...\n"); |
for(i=from; i<to; ) { |
struct label_entry *entry; |
unsigned int _insn; |
PRINTF("i=%x :: ", i); |
|
if (verify_memoryarea(i) && (entry = get_label(i))) |
PRINTF("label: %s |", entry->name); |
|
iqueue[0].insn = _insn = evalsim_mem32(i); |
iqueue[0].insn_index = insn_decode(_insn); |
disassemble_insn (_insn); |
PRINTF("%08x %s\n", _insn, disassembled); |
i += insn_len( iqueue[0].insn_index ); |
} |
} |
|
static int sim_cmd_quit(int argc, char **argv) /* quit */ |
{ |
PRINTF ("\n"); |
sim_done(); |
return 0; |
} |
|
static int sim_cmd_help(int argc, char **argv) /* help */ |
{ |
PRINTF("q - quit simulator\n"); |
PRINTF("r - display all registers\n"); |
PRINTF("t - execute next instruction\n"); |
PRINTF("run <instructions> [<hush>] - execute <instruction> instructions, no reg dump if hush\n"); |
PRINTF("pr <r> <value> - patch register <r> with <value>\n"); |
PRINTF("dm <fromaddr> [<toaddr>] - display memory from <fromaddr> to <toaddr>\n"); |
PRINTF("de <fromaddr> [<toaddr>] - debug insn memory\n"); |
PRINTF("pm <addr> <value> - patch memory location <addr> with <value>\n"); |
PRINTF("pc <value> - patch PC register with <value>\n"); |
PRINTF("cm <fromaddr> <toaddr> <size> - copy memory\n"); |
PRINTF("break <addr> - toggle breakpoint at address <addr>\n"); |
PRINTF("breaks - print all set breakpoints\n"); |
PRINTF("reset - simulator reset\n"); |
PRINTF("hist - execution history\n"); |
PRINTF("stall - stalls the processor and gives control to the debugger\n"); |
PRINTF("stats <num|clear> - execution statistics num or clear it.\n"); |
PRINTF("info - configuration info (caches etc.)\n"); |
PRINTF("dv <fromaddr> [<toaddr>] [<modname>] - dumps memory as verilog (use redirect)\n"); |
PRINTF("dh <fromaddr> [<toaddr>] - dumps memory as hex code (use redirect)\n"); |
PRINTF("<cmd> > <filename> - redirect simulator stdout to <filename> (and not emulated PRINTF)\n"); |
#if !FAST_SIM |
PRINTF("set <section> <item> = <param> - set configuration. See sim.cfg for more information.\n"); |
PRINTF("debug - toggles simulator debug mode\n"); |
mp_help (); |
prof_help (); |
PRINTF("cuc - enters Custom Unit Compiler command prompt\n"); |
#endif |
PRINTF("help - available commands (this list)\n"); |
return 0; |
} |
|
static int sim_cmd_trace(int argc, char **argv) /* trace */ |
{ |
runtime.sim.cont_run = 1; |
return 1; |
} |
|
static int sim_cmd_dm(int argc, char **argv) /* dump memory */ |
{ |
static oraddr_t from = 0, to = 0; |
|
if(argc >= 2) { |
if(argv[1][0] == '_') |
from = eval_label(argv[1]); |
else |
from = strtoul(argv[1], NULL, 0); |
to = from + 0x40; |
} |
if(argc >= 3) |
to = strtoul(argv[2], NULL, 0); |
dumpmemory(from, to, 0, 1); |
PRINTF("\n"); |
return 0; |
} |
|
static int sim_cmd_dv(int argc, char **argv) /* dump memory as verilog*/ |
{ |
static oraddr_t from = 0, to = 0; |
|
if(argc >= 2) { |
if(argv[1][0] == '_') |
from = eval_label(argv[1]); |
else |
from = strtoul(argv[1], NULL, 0); |
to = from + 0x40; |
} |
if(argc >= 3) |
to = strtoul(argv[2], NULL, 0); |
|
if(argc < 4) |
dumpverilog("or1k_mem", from, to); |
else |
dumpverilog(argv[3], from, to); |
|
PRINTF("\n"); |
return 0; |
} |
|
static int sim_cmd_dh(int argc, char **argv) /* dump memory as hex*/ |
{ |
static oraddr_t from = 0, to = 0; |
|
if(argc >= 2) { |
if(argv[1][0] == '_') |
from = eval_label(argv[1]); |
else |
from = strtoul(argv[1], NULL, 0); |
to = from + 0x40; |
} |
if(argc >= 3) |
to = strtoul(argv[2], NULL, 0); |
|
dumphex(from, to); |
PRINTF("\n"); |
return 0; |
} |
|
static int sim_cmd_pm(int argc, char **argv) /* patch memory */ |
{ |
static oraddr_t addr = 0; |
int breakpoint = 0; |
|
if(argc != 3) { |
PRINTF("pm <address> <value>\n"); |
return 0; |
} |
|
if(argc >= 2) { |
if (argv[1][0] == '_') |
addr = eval_label(argv[1]); |
else |
addr = strtoul(argv[1], NULL, 0); |
} |
set_mem32(addr, strtoul(argv[2], NULL, 0), &breakpoint); |
return 0; |
} |
|
static int sim_cmd_cm(int argc, char **argv) /* copy memory 2004-01-20 hpanther*/ |
{ |
static oraddr_t from = 0, to = 0; |
static unsigned int size = 0; |
int i; |
|
if(argc >= 2) { |
if (argv[1][0] == '_') |
from = eval_label(argv[1]); |
else |
from = strtoul(argv[1], NULL, 0); |
} |
|
if(argc >= 3) { |
if (argv[2][0] == '_') |
to = eval_label(argv[2]); |
else |
to = strtoul(argv[2], NULL, 0); |
} |
|
if(argc >= 4) { |
if (argv[3][0] == '_') |
size = eval_label(argv[3]); |
else |
size = strtoul(argv[3], NULL, 0); |
} |
|
for(i = 0; i < size; i += 4) |
setsim_mem32(to + i, evalsim_mem32(from + i)); |
return 0; |
} |
|
static int sim_cmd_pr(int argc, char **argv) /* patch regs */ |
{ |
if(argc != 3) { |
PRINTF("pr <register> <value>\n"); |
return 0; |
} |
setsim_reg(strtoul(argv[1], NULL,0), strtoul(argv[2], NULL, 0)); |
return 0; |
} |
|
static int sim_cmd_pc(int argc, char **argv) /* patch PC */ |
{ |
if(argc != 2) { |
PRINTF("pc <value>\n"); |
return 0; |
} |
|
pc = strtoul(argv[1], NULL, 0); |
pcnext = pc + 4; |
return 0; |
} |
|
static int sim_cmd_breaks(int argc, char **argv) /* print breakpoints */ |
{ |
print_breakpoints(); |
return 0; |
} |
|
static int sim_cmd_break(int argc, char **argv) /* set/clear breakpoint */ |
{ |
char *p; |
oraddr_t addr; |
struct label_entry *l; |
|
if(argc != 2) { |
PRINTF("break <label or address>\n"); |
return 0; |
} |
|
addr = strtoul(argv[1], &p, 0); |
if(*p) { |
l = find_label(argv[1]); |
if(l) |
addr = l->addr; |
else |
PRINTF("Label `%s' does not exist\n", l->name); |
} |
set_insnbrkpoint(addr); |
return 0; |
} |
|
static int sim_cmd_r(int argc, char **argv) /* dump regs */ |
{ |
dumpreg(); |
return 0; |
} |
|
static int sim_cmd_de(int argc, char **argv) /* disassemble */ |
{ |
static oraddr_t from = 0, to = 0; |
|
if(argc >= 2) { |
if (argv[1][0] == '_') |
from = eval_label(argv[1]); |
else |
from = strtoul(argv[1], NULL, 0); |
to = from + 0x40; |
} |
|
if(argc >= 3) |
to = strtoul(argv[2], NULL, 0); |
|
debugmem(from, to); |
PRINTF("\n"); |
return 0; |
} |
|
static int sim_cmd_reset(int argc, char **argv) /* reset simulator */ |
{ |
sim_reset(); |
return 0; |
} |
|
static int sim_cmd_hist(int argc, char **argv) /* dump history */ |
{ |
int i; |
struct hist_exec *cur; |
if(!config.sim.history) { |
PRINTF("Simulation history disabled.\n"); |
return 0; |
} |
for(i = HISTEXEC_LEN, cur = hist_exec_tail->prev; i; i--, cur = cur->prev) |
dumpmemory(cur->addr, cur->addr + 4, 1, 1); |
PRINTF("\n"); |
return 0; |
} |
|
static int sim_cmd_run(int argc, char **argv) /* run */ |
{ |
if(argc >= 3) { |
if(!strcmp(argv[2], "hush")) |
runtime.sim.hush = 1; |
else |
runtime.sim.hush = 0; |
} |
|
if(argc >= 2) |
runtime.sim.cont_run = strtol(argv[1], NULL, 0); |
else |
runtime.sim.cont_run = 0; |
return 1; |
} |
|
static int sim_cmd_stall(int argc, char **argv) /* Added by CZ 210801 */ |
{ |
set_stall_state (1); |
runtime.sim.iprompt = 0; |
runtime.sim.cont_run = -1; |
runtime.sim.hush = 1; |
return 1; |
} |
|
static int sim_cmd_stats(int argc, char **argv) /* stats */ |
{ |
if(argc != 2) { |
PRINTF("stats <stat no. or `clear'>\n"); |
return 0; |
} |
|
if(strcmp(argv[1], "clear") == 0) { |
initstats(); |
PRINTF("Cleared.\n"); |
} else { |
printstats(strtoul(argv[1], NULL, 0)); |
} |
return 0; |
} |
|
static int sim_cmd_info(int argc, char **argv) /* configuration info */ |
{ |
/* Display info about various modules */ |
sprs_status(); |
PRINTF ("\n"); |
memory_table_status (); |
if (config.immu.enabled) itlb_status(-1); |
if (config.dmmu.enabled) dtlb_status(-1); |
if (config.ic.enabled) ic_info(); |
if (config.dc.enabled) dc_info(); |
|
if (config.bpb.enabled) bpb_info(); |
if (config.bpb.btic) btic_info(); |
|
if (config.mc.enabled) mc_status(); |
if (config.nuarts) uart_status(); |
if (config.ndmas) dma_status(); |
if (config.nethernets) eth_status(); |
if (config.ngpios) gpio_status(); |
if (config.natas) ata_status(); |
kbd_info(); |
return 0; |
} |
|
#if !FAST_SIM |
static int sim_cmd_debug(int argc, char **argv) /* debug mode */ |
{ |
config.sim.debug ^= 1; |
return 0; |
} |
|
static int sim_cmd_profile(int argc, char **argv) /* run profiler utility */ |
{ |
main_profiler(argc, argv); |
return 0; |
} |
|
static int sim_cmd_mprofile(int argc, char **argv) /* run mprofiler utility */ |
{ |
main_mprofiler(argc, argv); |
return 0; |
} |
|
static int sim_cmd_cuc(int argc, char **argv) /* run Custom Unit Compiler */ |
{ |
main_cuc(runtime.sim.filename); |
return 0; |
} |
|
static int sim_cmd_set(int argc, char **argv) /* configuration info */ |
{ |
set_config_command(argc, argv); |
return 0; |
} |
#endif /* !FAST_SIM */ |
|
static char *strip_space(char *str) |
{ |
while(isblank(*str) && *str) str++; |
return str; |
} |
|
struct sim_command { |
const char *name; |
int (*cmd_handle)(int argc, char **argv); |
}; |
|
static const struct sim_command sim_commands[] = { |
{ "q", sim_cmd_quit }, |
{ "help", sim_cmd_help }, |
{ "t", sim_cmd_trace }, |
{ "dm", sim_cmd_dm }, |
{ "dv", sim_cmd_dv }, |
{ "dh", sim_cmd_dh }, |
{ "pm", sim_cmd_pm }, |
{ "cm", sim_cmd_cm }, |
{ "pr", sim_cmd_pr }, |
{ "pc", sim_cmd_pc }, |
{ "breaks", sim_cmd_breaks }, |
{ "break", sim_cmd_break }, |
{ "r", sim_cmd_r }, |
{ "de", sim_cmd_de }, |
{ "reset", sim_cmd_reset }, |
{ "hist", sim_cmd_hist }, |
{ "stall", sim_cmd_stall }, |
{ "stats", sim_cmd_stats }, |
{ "info", sim_cmd_info }, |
{ "run", sim_cmd_run }, |
#if !FAST_SIM |
{ "debug", sim_cmd_debug }, |
{ "profile", sim_cmd_profile }, |
{ "mprofile", sim_cmd_mprofile }, |
{ "cuc", sim_cmd_cuc }, |
{ "set", sim_cmd_set }, |
#endif |
{ NULL, NULL } }; |
|
#ifdef HAVE_LIBREADLINE |
static void initialize_readline(void); |
#endif |
|
void handle_sim_command(void) |
{ |
char *redirstr; |
int argc; |
char *argv[5]; |
char *cur_arg; |
const struct sim_command *cur_cmd; |
#ifdef HAVE_LIBREADLINE |
static char *prev_str = NULL; |
#else |
char b2[500]; |
static char prev_str[500] = { 0 }; |
#endif |
|
#ifdef HAVE_LIBREADLINE |
initialize_readline (); /* Bind our completer. */ |
#endif |
|
for(;;) { |
#ifdef HAVE_LIBREADLINE |
cur_arg = readline("(sim) "); |
#else |
PRINTF("(sim) "); |
if(config.debug.gdb_enabled) { |
fflush(stdout); |
HandleServerSocket(true); /* block & check_stdin = true */ |
} |
|
cur_arg = fgets(b2, sizeof(b2), stdin); |
|
if (!*cur_arg) { |
usleep(1000); |
continue; |
} |
#endif |
|
#ifdef HAVE_LIBREADLINE |
if(!*cur_arg) { |
if(prev_str) { |
free(cur_arg); |
cur_arg = prev_str; |
} |
} else { |
prev_str = cur_arg; |
add_history(cur_arg); |
} |
#else |
cur_arg = strip_space(cur_arg); |
if(*cur_arg == '\n') |
strcpy(cur_arg, prev_str); |
else |
strcpy(prev_str, cur_arg); |
#endif |
|
if((redirstr = strchr(cur_arg, '>'))) { |
redirstr = strip_space(++redirstr); |
|
while(!isspace(*redirstr) && *redirstr) redirstr++; |
*redirstr = '\0'; |
|
redirstr = strchr(cur_arg, '>'); |
*redirstr = '\0'; |
|
redirstr = strip_space(++redirstr); |
runtime.sim.fout = fopen(redirstr, "w+"); |
if (!runtime.sim.fout) runtime.sim.fout = stdout; |
} |
|
if(*cur_arg) { |
argc = 0; |
while(*cur_arg) { |
argv[argc] = cur_arg; |
argc++; |
while(!isspace(*cur_arg) && *cur_arg) cur_arg++; |
if(*cur_arg) { |
*cur_arg = '\0'; |
cur_arg = strip_space(cur_arg + 1); |
} else |
*cur_arg = '\0'; |
if(argc == 5) { |
fprintf(stderr, "Too many arguments given to command `%s'\n", argv[0]); |
break; |
} |
} |
|
for(cur_cmd = sim_commands; cur_cmd->name; cur_cmd++) { |
if(!strcmp(cur_cmd->name, argv[0])) { |
if(cur_cmd->cmd_handle(argc, argv)) |
return; |
break; |
} |
} |
|
if(!cur_cmd->name) |
PRINTF("%s: Unknown command.\n", argv[0]); |
} |
} |
} |
|
#ifdef HAVE_LIBREADLINE |
|
int check_gdb_comm(void) |
{ |
HandleServerSocket(true); /* block & check_stdin = true */ |
return 0; |
} |
|
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. */ |
static void initialize_readline(void) |
{ |
/* Allow conditional parsing of the ~/.inputrc file. */ |
rl_readline_name = "or1ksim"; |
|
/* Tell the completer that we want a crack first. */ |
rl_attempted_completion_function = sim_completion; |
|
/* Handle the gdb socket while waiting for input */ |
rl_event_hook = check_gdb_comm; |
} |
|
/* 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. */ |
/* FIXME: Handle arguments to the `set' command */ |
char **sim_completion(char *text, int start, int end) |
{ |
char **matches; |
|
matches = 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) |
matches = rl_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(char *text, int state) |
{ |
static int list_index, len; |
const 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].name)) { |
list_index++; |
|
if(strncmp(name, text, len) == 0) |
return strdup(name); |
} |
|
/* If no names matched, then return NULL. */ |
return NULL; |
} |
|
/* Repeats the last command. */ |
char *repeat_last_command () |
{ |
int offset = where_history (); |
HIST_ENTRY *hist; |
|
if((hist = history_get(offset))) |
return strdup(hist->line); |
return 0; |
} |
|
#endif |
|
/trunk/or1ksim/Makefile.am
9,7 → 9,7
bin_PROGRAMS = sim |
|
sim_SOURCES = toplevel.c sim-config.c sim-config.h profiler.c \ |
mprofiler.c profiler.h mprofiler.h |
mprofiler.c profiler.h mprofiler.h sim-cmd.c |
sim_LDADD = cpu/common/libcommon.a cpu/$(CPU_ARCH)/libarch.a \ |
cpu/or1k/libor1k.a support/libsupport.a mmu/libmmu.a \ |
bpb/libbpb.a cache/libcache.a peripheral/libperipheral.a \ |
/trunk/or1ksim/toplevel.c
38,11 → 38,6
#include <inttypes.h> |
#endif |
|
#ifdef HAVE_LIBREADLINE |
#include <readline/readline.h> |
#include <readline/history.h> |
#endif /* HAVE_LIBREADLINE */ |
|
#include "port.h" |
#include "arch.h" |
#include "parse.h" |
82,18 → 77,8
#include "cuc.h" |
|
/* CVS revision number. */ |
const char rcsrev[] = "$Revision: 1.102 $"; |
const char rcsrev[] = "$Revision: 1.103 $"; |
|
char *sim_commands [] = { |
"q", "t", "help", "de", "dm", "run", "pr", "pm", "pc", |
"reset", "break", "breaks", "hist", "stats", "stall" "info", |
"r", "dv", |
#if !FAST_SIM |
"set", |
#endif |
0 |
}; |
|
inline void debug(int level, const char *format, ...) |
{ |
char *p; |
152,43 → 137,10
PRINTF ("for details see COPYING.\n"); |
} |
|
void |
help() |
{ |
PRINTF("q - quit simulator\n"); |
PRINTF("r - display all registers\n"); |
PRINTF("t - execute next instruction\n"); |
PRINTF("run <instructions> [<hush>] - execute <instruction> instructions, no reg dump if hush\n"); |
PRINTF("pr <r> <value> - patch register <r> with <value>\n"); |
PRINTF("dm <fromaddr> [<toaddr>] - display memory from <fromaddr> to <toaddr>\n"); |
PRINTF("de <fromaddr> [<toaddr>] - debug insn memory\n"); |
PRINTF("pm <addr> <value> - patch memory location <addr> with <value>\n"); |
PRINTF("pc <value> - patch PC register with <value>\n"); |
PRINTF("cm <fromaddr> <toaddr> <size> - copy memory\n"); |
PRINTF("break <addr> - toggle breakpoint at address <addr>\n"); |
PRINTF("breaks - print all set breakpoints\n"); |
PRINTF("reset - simulator reset\n"); |
PRINTF("hist - execution history\n"); |
PRINTF("stall - stalls the processor and gives control to the debugger\n"); |
PRINTF("stats <num|clear> - execution statistics num or clear it.\n"); |
PRINTF("info - configuration info (caches etc.)\n"); |
PRINTF("dv <fromaddr> [<toaddr>] [<modname>] - dumps memory as verilog (use redirect)\n"); |
PRINTF("dh <fromaddr> [<toaddr>] - dumps memory as hex code (use redirect)\n"); |
PRINTF("<cmd> > <filename> - redirect simulator stdout to <filename> (and not emulated PRINTF)\n"); |
#if !FAST_SIM |
PRINTF("set <section> <item> = <param> - set configuration. See sim.cfg for more information.\n"); |
PRINTF("debug - toggles simulator debug mode\n"); |
mp_help (); |
prof_help (); |
PRINTF("cuc - enters Custom Unit Compiler command prompt\n"); |
#endif |
PRINTF("help - available commands (this list)\n"); |
} |
|
void debugmem (unsigned long from, unsigned long to ); |
|
/* Resets all subunits */ |
void sim_reset () |
void sim_reset (void) |
{ |
SCHED_INIT(); |
uart_reset(); |
351,28 → 303,6
runtime.sim.init = 0; |
} |
|
/* Display info about various modules */ |
void sim_info () { |
sprs_status(); |
PRINTF ("\n"); |
memory_table_status (); |
if (config.immu.enabled) itlb_status(-1); |
if (config.dmmu.enabled) dtlb_status(-1); |
if (config.ic.enabled) ic_info(); |
if (config.dc.enabled) dc_info(); |
|
if (config.bpb.enabled) bpb_info(); |
if (config.bpb.btic) btic_info(); |
|
if (config.mc.enabled) mc_status(); |
if (config.nuarts) uart_status(); |
if (config.ndmas) dma_status(); |
if (config.nethernets) eth_status(); |
if (config.ngpios) gpio_status(); |
if (config.natas) ata_status(); |
kbd_info(); |
} |
|
/* Cleanup */ |
void sim_done () |
{ |
388,20 → 318,6
exit(0); |
} |
|
/* change result if item found in linestr */ |
static void addr_from_linestr(char *linestr, int index, int *result) |
{ |
char item[20]; |
strtoken(linestr, item, index); |
if (strlen(item)) |
{ |
if (item[0] == '_') |
*result = eval_label(item); |
else |
*result = strtoul(item, NULL, 0); |
}; |
}; |
|
/* Executes jobs in time queue */ |
static inline void do_scheduler () |
{ |
422,11 → 338,6
int argc; |
char *argv[]; |
{ |
char *linestr; |
char item1[500], b2[500], prev_str[500] = ""; |
char *redirstr; |
int hush = 0; |
|
srand(getpid()); |
init_defconfig(); |
if (parse_args(argc, argv)) { |
450,10 → 361,6
exit(-1); |
} |
|
#ifdef HAVE_LIBREADLINE |
initialize_readline (); /* Bind our completer. */ |
#endif |
|
#if !FAST_SIM |
/* Read configuration file. */ |
if (!runtime.sim.script_file_specified) |
476,294 → 383,13
sim_init (); |
signal(SIGINT, ctrl_c); |
|
runtime.sim.hush = 1; |
runtime.sim.cont_run = -1; |
|
while(1) { |
if (runtime.sim.iprompt) { |
if (config.debug.gdb_enabled) |
{ |
PRINTF ("(sim) "); |
fflush(stdout); |
HandleServerSocket(true); /* block & check_stdin = true */ |
} |
#ifdef HAVE_LIBREADLINE |
/* Must disable readline in new mode. It isn't compatible |
with non blocking environments */ |
wait_input: |
if(!config.debug.gdb_enabled) |
linestr = readline("(sim) "); |
else |
linestr = fgets(b2, sizeof b2, stdin); |
#else |
if(!config.debug.gdb_enabled) |
PRINTF ("(sim) "); |
wait_input: |
linestr = fgets(b2, sizeof b2, stdin); |
#endif |
} else |
strcpy(linestr = b2, "run -1 hush"); |
if (runtime.sim.iprompt) |
handle_sim_command(); |
|
if (!linestr) { |
usleep (1000); |
goto wait_input; |
} |
linestr = stripwhite (linestr); |
|
#ifdef HAVE_LIBREADLINE |
/* Readline only works in the old mode */ |
if(!server_fd) |
{ |
if (strlen(linestr) == 0) { |
char *l = repeat_last_command (); |
|
if (l) { |
free (linestr); |
linestr = l; |
} |
} |
|
if (*linestr) { |
add_history (linestr); |
} |
} |
#endif /* HAVE_LIBREADLINE */ |
|
if ((redirstr = strstr(linestr, ">"))) { |
*redirstr = '\0'; |
strtoken(&redirstr[1], item1, 1); |
runtime.sim.fout = fopen(item1, "w+"); |
if (!runtime.sim.fout) runtime.sim.fout = stdout; |
} |
|
if (linestr[0] == '\n') |
strcpy (linestr, &prev_str[0]); |
else |
strcpy (&prev_str[0], linestr); |
|
strtoken(linestr, item1, 1); |
if (strcmp(item1, "q") == 0) { /* quit */ |
PRINTF ("\n"); |
sim_done (); |
} else |
if (strcmp(item1, "help") == 0) /* help */ |
help(); |
else |
if (strcmp(item1, "t") == 0) { /* trace */ |
runtime.sim.cont_run = 1; |
} else |
if (strcmp(item1, "dm") == 0) { /* dump memory */ |
char item2[20]; |
char item3[20]; |
static int from = 0, to = 0; |
|
strtoken(linestr, item2, 2); |
strtoken(linestr, item3, 3); |
|
if (strlen(item2)) { |
if (item2[0] == '_') |
from = eval_label(item2); |
else |
from = strtoul(item2, NULL, 0); |
to = from + 0x40; |
} |
if (strlen(item3)) |
to = strtoul(item3, NULL, 0); |
dumpmemory(from, to, 0, 1); |
PRINTF("\n"); |
} else |
if (strcmp(item1, "dv") == 0) {/* dump memory as verilog*/ |
char item2[20]; |
char item3[20]; |
char item4[20]; |
static int from = 0, to = 0; |
|
strtoken(linestr, item2, 2); |
strtoken(linestr, item3, 3); |
strtoken(linestr, item4, 4); |
|
if (strlen(item2)) { |
if (item2[0] == '_') |
from = eval_label(item2); |
else |
from = strtoul(item2, NULL, 0); |
to = from + 0x40; |
} |
if (strlen(item3)) |
to = strtoul(item3, NULL, 0); |
if (!strlen(item4)) |
strcpy(item4, "or1k_mem"); |
dumpverilog(item4, from, to); |
PRINTF("\n"); |
} else |
if (strcmp(item1, "dh") == 0) {/* dump memory as hex*/ |
char item2[20]; |
char item3[20]; |
static int from = 0, to = 0; |
|
strtoken(linestr, item2, 2); |
strtoken(linestr, item3, 3); |
|
if (strlen(item2)) { |
if (item2[0] == '_') |
from = eval_label(item2); |
else |
from = strtoul(item2, NULL, 0); |
to = from + 0x40; |
} |
if (strlen(item3)) |
to = strtoul(item3, NULL, 0); |
dumphex(from, to); |
PRINTF("\n"); |
} else |
if (strcmp(item1, "pm") == 0) { /* patch memory */ |
char item2[20]; |
char item3[20]; |
static int addr = 0; |
int breakpoint = 0; |
|
strtoken(linestr, item2, 2); |
strtoken(linestr, item3, 3); |
if (strlen(item2)) { |
if (item2[0] == '_') |
addr = eval_label(item2); |
else |
addr = strtoul(item2, NULL, 0); |
} |
set_mem32(addr, strtoul(item3, NULL, 0), &breakpoint); |
} else |
if (strcmp(item1, "cm") == 0) { /* copy memory 2004-01-20 hpanther*/ |
static int from=0, to=0, size=0; |
int i; |
addr_from_linestr(linestr, 2, &from); |
addr_from_linestr(linestr, 3, &to); |
addr_from_linestr(linestr, 4, &size); |
for(i=0; i<size; i+=4) |
setsim_mem32(to+i, evalsim_mem32(from+i)); |
} else |
if (strcmp(item1, "pr") == 0) { /* patch regs */ |
char item2[20]; |
char item3[20]; |
|
strtoken(linestr, item2, 2); |
strtoken(linestr, item3, 3); |
setsim_reg(strtoul(item2, NULL,0), strtoul(item3, NULL, 0)); |
} else |
if (strcmp(item1, "pc") == 0) { /* patch PC */ |
char item2[20]; |
|
strtoken(linestr, item2, 2); |
pc = strtoul(item2, NULL, 0); |
} else |
if (strcmp(item1, "breaks") == 0) { /* print breakpoints */ |
print_breakpoints(); |
} else |
if (strcmp(item1, "break") == 0) { /* set/clear breakpoint */ |
char item2[20]; |
char *p; |
unsigned long addr; |
strtoken(linestr, item2, 2); |
addr = strtoul(item2, &p, 0); |
if (*p) { |
struct label_entry *l = find_label (item2); |
if (l) { |
addr = l->addr; |
} else addr = 0xffffffff; |
} |
if (addr != 0xffffffff) set_insnbrkpoint(addr); |
else PRINTF ("'%s' is invalid address!\n"); |
} else |
if (strcmp(item1, "r") == 0) { /* dump regs */ |
dumpreg(); |
} else |
if (strcmp(item1, "de") == 0) { /* reset simulator */ |
char item2[20]; |
char item3[20]; |
static int from = 0, to = 0; |
|
strtoken(linestr, item2, 2); |
strtoken(linestr, item3, 3); |
|
if (strlen(item2)) { |
if (item2[0] == '_') |
from = eval_label(item2); |
else |
from = strtoul(item2, NULL, 0); |
to = from + 0x40; |
} |
if (strlen(item3)) |
to = strtoul(item3, NULL, 0); |
debugmem(from, to); |
PRINTF("\n"); |
} else |
if (strcmp(item1, "reset") == 0) { /* reset simulator */ |
sim_reset(); |
} else |
#if !FAST_SIM |
if (strcmp(item1, "debug") == 0) { /* debug mode */ |
config.sim.debug ^= 1; |
} else |
#endif |
if (strcmp(item1, "hist") == 0) { /* dump history */ |
int i; |
struct hist_exec *cur; |
for(i = HISTEXEC_LEN, cur = hist_exec_tail->prev; i; i--, cur = cur->prev) |
dumpmemory(cur->addr, cur->addr + 4, 1, 1); |
PRINTF("\n"); |
} else |
if (strcmp(item1, "run") == 0) { /* run */ |
char item2[20]; |
char item3[20]; |
|
strtoken(linestr, item2, 2); |
strtoken(linestr, item3, 3); |
if (strcmp(item3, "hush") == 0) |
hush = 1; |
else |
hush = 0; |
runtime.sim.cont_run = strtol(item2, NULL, 0); |
} else |
if(!strcmp(item1, "stall")) { /* Added by CZ 210801 */ |
set_stall_state (1); |
runtime.sim.iprompt = 0; |
runtime.sim.cont_run = -1; |
hush = 1; |
} else |
if (strcmp(item1, "stats") == 0) { /* stats */ |
char item2[20]; |
int i = 0; |
|
strtoken(linestr, item2, 2); |
if (strcmp(item2, "clear") == 0) { |
initstats(); |
PRINTF("Cleared.\n"); |
} else { |
i = strtoul(item2, NULL, 0); |
printstats(i); |
} |
} else |
if (strcmp(item1, "info") == 0) /* configuration info */ |
sim_info (); |
else |
#if !FAST_SIM |
if (strcmp (item1, "profiler") == 0) { /* run profiler utility */ |
char *argv[10]; |
int argc = tokenize_line (linestr, argv, 10); |
main_profiler (argc, argv); |
} else |
if (strcmp (item1, "mprofiler") == 0) { /* run mprofiler utility */ |
char *argv[10]; |
int argc = tokenize_line (linestr, argv, 10); |
main_mprofiler (argc, argv); |
} else |
if (strcmp (item1, "cuc") == 0) { /* run Custom Unit Compiler */ |
main_cuc (runtime.sim.filename); |
} else |
if (strcmp(item1, "set") == 0) { /* configuration info */ |
char *s = linestr; |
while (*s != ' ' && *s) s++; |
set_config_command (s); |
} else |
#endif /* !FAST_SIM */ |
PRINTF("%s: Unknown command.\n", linestr); |
|
{ /* Needed by execution */ |
extern int do_stats; |
do_stats = config.cpu.dependstats || config.cpu.superscalar || config.cpu.dependstats |
773,7 → 399,7
/* MM: 'run -1' means endless execution. */ |
while(runtime.sim.cont_run) { |
IFF (config.debug.enabled) { |
du_clock(); // reset watchpoints etc. |
du_clock(); // reset watchpoints |
if (runtime.cpu.stalled) { |
if(config.debug.gdb_enabled) { |
BlockJTAG(); |
808,127 → 434,16
|
runtime.sim.cycles += runtime.sim.mem_cycles; |
if (runtime.sim.cycles >= SCHED_PEEK().time) do_scheduler (); |
if (!hush) dumpreg(); |
if (!runtime.sim.hush) dumpreg(); |
} |
hush = 0; |
runtime.sim.hush = 0; |
fflush(stdout); |
runtime.sim.fout = stdout; |
|
if (!runtime.sim.iprompt) /* non-interactive quit */ |
sim_done(); |
|
#ifdef HAVE_LIBREADLINE |
if (linestr) |
free (linestr); |
#endif |
|
} |
sim_done(); |
} |
|
#ifdef HAVE_LIBREADLINE |
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); |
} |
|
/* 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; |
} |
|
#endif |
|
extern char *disassembled; |
void debugmem( unsigned long from, unsigned long to ) |
{ |
int i; |
PRINTF("starting to dump mem...\n"); |
for(i=from; i<to; ) { |
struct label_entry *entry; |
unsigned int _insn; |
PRINTF("i=%x :: ", i); |
|
if (verify_memoryarea(i) && (entry = get_label(i))) |
PRINTF("label: %s |", entry->name); |
|
iqueue[0].insn = _insn = evalsim_mem32(i); |
iqueue[0].insn_index = insn_decode(_insn); |
disassemble_insn (_insn); |
PRINTF("%08x %s\n", _insn, disassembled); |
i += insn_len( iqueue[0].insn_index ); |
} |
} |
/trunk/or1ksim/sim-config.c
319,7 → 319,7
if (!isspace (ch)) { |
char tmp[200]; |
sprintf (tmp, "unexpected char '%c' (expecting '%c')\n", ch, *fmt); |
fprintf (stderr, "WARNING: config.%s: %s\n", sections[section], tmp); |
fprintf (stderr, "WARNING: config.%s: %s\n", sections[section].name, tmp); |
WARNING(tmp); |
} |
if ((f ? feof (f) : *str)) return 1; |
1397,42 → 1397,29
} |
|
/* Utility for execution of set sim command. */ |
static int set_config (char *s) |
static int set_config (int argc, char **argv) |
{ |
char *sec, *item, *params; |
int noparams = 0, i, noitem = 0; |
while (*s && isspace (*s)) s++; |
sec = s; |
PRINTF ("s:%s\n", s); |
while (*s && *s != ' ') s++; |
if (!(*s)) noitem = 1; |
*s = 0; |
PRINTF ("sec:%s\n", sec); |
int i; |
|
if (argc < 2) return 1; |
|
PRINTF ("sec:%s\n", argv[1]); |
section = 0; |
for (i = 1; i < sizeof(sections) / sizeof(struct section); i++) |
if (strcmp (sections[i].name, sec) == 0) { |
if (strcmp (sections[i].name, argv[1]) == 0) { |
section = i; |
break; |
} |
|
if (!section) return 1; |
if (noitem) return 2; |
|
if (argc < 3) return 2; |
|
item = ++s; |
|
while (*s && *s != ' ') s++; |
if (!(*s)) { |
noparams = 1; |
params = ""; |
} else |
params = s + 1; |
*s = 0; |
PRINTF ("item:%s\n", item); |
PRINTF ("params:%s\n", params); |
PRINTF ("item:%s\n", argv[2]); |
{ |
int i, found = -1; |
int found = -1; |
for (i = 0; i < sizeof(config_params)/sizeof(struct config_params); i++) |
if (config_params[i].section == section && strcmp (config_params[i].name, item) == 0) { |
if (config_params[i].section == section && strcmp (config_params[i].name, argv[2]) == 0) { |
found = i; |
break; |
} |
1439,9 → 1426,12
if (found < 0) return 2; |
|
/* Parse parameter value */ |
if (config_params[found].type[0]) |
if(fscanf_ex (0, config_params[found].type, config_params[found].addr, params)) |
if (config_params[found].type[0]) { |
if (argc < 4) return 3; |
if (fscanf_ex (0, config_params[found].type, config_params[found].addr, argv[3])) |
return 3; |
PRINTF ("params:%s\n", argv[3]); |
} |
if (config_params[found].func) |
config_params[found].func(); |
} |
1449,10 → 1439,11
} |
|
/* Executes set sim command, displays error. */ |
void set_config_command(char *s) |
void set_config_command(int argc, char **argv) |
{ |
int i; |
switch (set_config (s)) { |
|
switch (set_config (argc, argv)) { |
case 1: |
PRINTF ("Invalid or missing section name. One of valid sections must be specified:\n"); |
for (i = 1; i < sizeof(sections) / sizeof(struct section); i++) |