Line 58... |
Line 58... |
#include "mprofiler.h"
|
#include "mprofiler.h"
|
#include "mc.h"
|
#include "mc.h"
|
#include "atahost.h"
|
#include "atahost.h"
|
|
|
/* CVS revision number. */
|
/* CVS revision number. */
|
const char rcsrev[] = "$Revision: 1.96 $";
|
const char rcsrev[] = "$Revision: 1.97 $";
|
|
|
/* History of execution */
|
/* History of execution */
|
int histexec[HISTEXEC_LEN];
|
int histexec[HISTEXEC_LEN];
|
|
|
char *sim_commands [] = {
|
char *sim_commands [] = {
|
Line 143... |
Line 143... |
PRINTF("pr <r> <value> - patch register <r> with <value>\n");
|
PRINTF("pr <r> <value> - patch register <r> with <value>\n");
|
PRINTF("dm <fromaddr> [<toaddr>] - display memory from <fromaddr> to <toaddr>\n");
|
PRINTF("dm <fromaddr> [<toaddr>] - display memory from <fromaddr> to <toaddr>\n");
|
PRINTF("de <fromaddr> [<toaddr>] - debug insn memory\n");
|
PRINTF("de <fromaddr> [<toaddr>] - debug insn memory\n");
|
PRINTF("pm <addr> <value> - patch memory location <addr> with <value>\n");
|
PRINTF("pm <addr> <value> - patch memory location <addr> with <value>\n");
|
PRINTF("pc <value> - patch PC register with <value>\n");
|
PRINTF("pc <value> - patch PC register with <value>\n");
|
PRINTF("break <addr> - toggle breakpoint at address <addr>\n");
|
PRINTF("cm <fromaddr> <toaddr> <size> - copy memory
|
PRINTF("breaks - print all set breakpoints\n");
|
PRINTF("break <addr> - toggle breakpoint at address <addr>\n");
|
PRINTF("reset - simulator reset\n");
|
PRINTF("breaks - print all set breakpoints\n");
|
PRINTF("hist - execution history\n");
|
PRINTF("reset - simulator reset\n");
|
PRINTF("stall - stalls the processor and gives control to the debugger\n");
|
PRINTF("hist - execution history\n");
|
PRINTF("stats <num|clear> - execution statistics num or clear it.\n");
|
PRINTF("stall - stalls the processor and gives control to the debugger\n");
|
PRINTF("info - configuration info (caches etc.)\n");
|
PRINTF("stats <num|clear> - execution statistics num or clear it.\n");
|
PRINTF("dv <fromaddr> [<toaddr>] [<modname>] - dumps memory as verilog (use redirect)\n");
|
PRINTF("info - configuration info (caches etc.)\n");
|
PRINTF("dh <fromaddr> [<toaddr>] - dumps memory as hex code (use redirect)\n");
|
PRINTF("dv <fromaddr> [<toaddr>] [<modname>] - dumps memory as verilog (use redirect)\n");
|
PRINTF("<cmd> > <filename> - redirect simulator stdout to <filename> (and not emulated PRINTF)\n");
|
PRINTF("dh <fromaddr> [<toaddr>] - dumps memory as hex code (use redirect)\n");
|
#if !FAST_SIM
|
PRINTF("<cmd> > <filename> - redirect simulator stdout to <filename> (and not emulated PRINTF)\n");
|
PRINTF("set <section> <item> = <param> - set configuration. See sim.cfg for more information.\n");
|
#if !FAST_SIM
|
PRINTF("debug - toggles simulator debug mode\n");
|
PRINTF("set <section> <item> = <param> - set configuration. See sim.cfg for more information.\n");
|
mp_help ();
|
PRINTF("debug - toggles simulator debug mode\n");
|
prof_help ();
|
mp_help ();
|
PRINTF("cuc - enters Custom Unit Compiler command prompt\n");
|
prof_help ();
|
#endif
|
PRINTF("cuc - enters Custom Unit Compiler command prompt\n");
|
PRINTF("help - available commands (this list)\n");
|
#endif
|
}
|
PRINTF("help - available commands (this list)\n");
|
|
}
|
void debugmem (unsigned long from, unsigned long to );
|
|
|
void debugmem (unsigned long from, unsigned long to );
|
/* Resets all subunits */
|
|
void sim_reset ()
|
/* Resets all subunits */
|
{
|
void sim_reset ()
|
SCHED_INIT();
|
{
|
uart_reset();
|
SCHED_INIT();
|
dma_reset();
|
uart_reset();
|
eth_reset();
|
dma_reset();
|
gpio_reset();
|
eth_reset();
|
vga_reset ();
|
gpio_reset();
|
fb_reset ();
|
vga_reset ();
|
kbd_reset ();
|
fb_reset ();
|
ata_reset();
|
kbd_reset ();
|
tick_reset();
|
ata_reset();
|
pm_reset();
|
tick_reset();
|
pic_reset();
|
pm_reset();
|
mc_reset();
|
pic_reset();
|
du_reset ();
|
mc_reset();
|
cpu_reset();
|
du_reset ();
|
}
|
cpu_reset();
|
|
}
|
/* Initalizes all devices and sim */
|
|
void sim_init ()
|
/* Initalizes all devices and sim */
|
{
|
void sim_init ()
|
init_memory_table ();
|
{
|
init_labels();
|
init_memory_table ();
|
init_breakpoints();
|
init_labels();
|
initstats();
|
init_breakpoints();
|
build_automata();
|
initstats();
|
|
build_automata();
|
if (config.sim.profile) {
|
|
runtime.sim.fprof = fopen(config.sim.prof_fn, "wt+");
|
if (config.sim.profile) {
|
if(!runtime.sim.fprof) {
|
runtime.sim.fprof = fopen(config.sim.prof_fn, "wt+");
|
fprintf(stderr, "ERROR: Problems opening profile file.\n");
|
if(!runtime.sim.fprof) {
|
exit (1);
|
fprintf(stderr, "ERROR: Problems opening profile file.\n");
|
} else
|
exit (1);
|
fprintf(runtime.sim.fprof, "+00000000 FFFFFFFF FFFFFFFF [outside_functions]\n");
|
} else
|
}
|
fprintf(runtime.sim.fprof, "+00000000 FFFFFFFF FFFFFFFF [outside_functions]\n");
|
|
}
|
if (config.sim.mprofile) {
|
|
runtime.sim.fmprof = fopen(config.sim.mprof_fn, "wb+");
|
if (config.sim.mprofile) {
|
if(!runtime.sim.fmprof) {
|
runtime.sim.fmprof = fopen(config.sim.mprof_fn, "wb+");
|
fprintf(stderr, "ERROR: Problems opening memory profile file.\n");
|
if(!runtime.sim.fmprof) {
|
exit (1);
|
fprintf(stderr, "ERROR: Problems opening memory profile file.\n");
|
}
|
exit (1);
|
}
|
}
|
|
}
|
if (config.sim.exe_log) {
|
|
runtime.sim.fexe_log = fopen(config.sim.exe_log_fn, "wt+");
|
if (config.sim.exe_log) {
|
if(!runtime.sim.fexe_log) {
|
runtime.sim.fexe_log = fopen(config.sim.exe_log_fn, "wt+");
|
PRINTF("ERROR: Problems opening exe_log file.\n");
|
if(!runtime.sim.fexe_log) {
|
exit (1);
|
PRINTF("ERROR: Problems opening exe_log file.\n");
|
}
|
exit (1);
|
}
|
}
|
|
}
|
if (config.sim.spr_log) {
|
|
PRINTF("OPENING SPRLOG\n");
|
if (config.sim.spr_log) {
|
runtime.sim.fspr_log = fopen(config.sim.spr_log_fn, "wt+");
|
PRINTF("OPENING SPRLOG\n");
|
if (!runtime.sim.fspr_log) {
|
runtime.sim.fspr_log = fopen(config.sim.spr_log_fn, "wt+");
|
PRINTF("ERROR: Problems opening spr_log file.\n");
|
if (!runtime.sim.fspr_log) {
|
exit(1);
|
PRINTF("ERROR: Problems opening spr_log file.\n");
|
}
|
exit(1);
|
}
|
}
|
|
}
|
/* Initialize memory */
|
|
{
|
/* Initialize memory */
|
extern struct dev_memarea *dev_list;
|
{
|
struct dev_memarea *area;
|
extern struct dev_memarea *dev_list;
|
int i;
|
struct dev_memarea *area;
|
if (config.memory.type == MT_RANDOM) {
|
int i;
|
unsigned int val = 0;
|
if (config.memory.type == MT_RANDOM) {
|
|
unsigned int val = 0;
|
if (config.memory.random_seed == -1) {
|
|
runtime.memory.random_seed = time(NULL);
|
if (config.memory.random_seed == -1) {
|
/* Print out the seed just in case we ever need to debug */
|
runtime.memory.random_seed = time(NULL);
|
PRINTF("Seeding random generator with value %d\n", config.memory.random_seed);
|
/* Print out the seed just in case we ever need to debug */
|
} else
|
PRINTF("Seeding random generator with value %d\n", config.memory.random_seed);
|
runtime.memory.random_seed = config.memory.random_seed;
|
} else
|
srandom(runtime.memory.random_seed);
|
runtime.memory.random_seed = config.memory.random_seed;
|
|
srandom(runtime.memory.random_seed);
|
for (area = dev_list; area; area = area->next)
|
|
for(i = 0; i < area->size; i++) {
|
for (area = dev_list; area; area = area->next)
|
val = random();
|
for(i = 0; i < area->size; i++) {
|
setsim_mem8(i + area->addr_compare, val & 0xFF);
|
val = random();
|
}
|
setsim_mem8(i + area->addr_compare, val & 0xFF);
|
} else if(config.memory.type == MT_PATTERN) {
|
}
|
for (area = dev_list; area; area = area->next)
|
} else if(config.memory.type == MT_PATTERN) {
|
for(i = 0; i < area->size; i++)
|
for (area = dev_list; area; area = area->next)
|
setsim_mem8(i + area->addr_compare, config.memory.pattern);
|
for(i = 0; i < area->size; i++)
|
} else if (config.memory.type != MT_UNKNOWN) {
|
setsim_mem8(i + area->addr_compare, config.memory.pattern);
|
fprintf(stderr, "Invalid memory configuration type.\n");
|
} else if (config.memory.type != MT_UNKNOWN) {
|
exit(1);
|
fprintf(stderr, "Invalid memory configuration type.\n");
|
}
|
exit(1);
|
}
|
}
|
|
}
|
if(runtime.sim.filename) {
|
|
unsigned long endaddr = 0xFFFFFFFF;
|
if(runtime.sim.filename) {
|
endaddr = loadcode(runtime.sim.filename, 0, 0); /* MM170901 always load at address zero. */
|
unsigned long endaddr = 0xFFFFFFFF;
|
if (endaddr == -1) {
|
endaddr = loadcode(runtime.sim.filename, 0, 0); /* MM170901 always load at address zero. */
|
fprintf(stderr, "Problems loading boot code.\n");
|
if (endaddr == -1) {
|
exit(1);
|
fprintf(stderr, "Problems loading boot code.\n");
|
}
|
exit(1);
|
}
|
}
|
|
}
|
#if !FAST_SIM /* We assume we have valid configuration with fsim*/
|
|
/* Disable gdb debugging, if debug module is not available. */
|
#if !FAST_SIM /* We assume we have valid configuration with fsim*/
|
if (config.debug.gdb_enabled && !config.debug.enabled) {
|
/* Disable gdb debugging, if debug module is not available. */
|
config.debug.gdb_enabled = 0;
|
if (config.debug.gdb_enabled && !config.debug.enabled) {
|
if (config.sim.verbose)
|
config.debug.gdb_enabled = 0;
|
fprintf (stderr, "WARNING: Debug module not enabled, cannot start gdb.\n");
|
if (config.sim.verbose)
|
}
|
fprintf (stderr, "WARNING: Debug module not enabled, cannot start gdb.\n");
|
#endif
|
}
|
|
#endif
|
if (config.debug.gdb_enabled)
|
|
gdbcomm_init ();
|
if (config.debug.gdb_enabled)
|
|
gdbcomm_init ();
|
#if !FAST_SIM /* We assume we have valid configuration with fsim*/
|
|
/* Enable dependency stats, if we want to do history analisis */
|
#if !FAST_SIM /* We assume we have valid configuration with fsim*/
|
if (config.sim.history && !config.cpu.dependstats) {
|
/* Enable dependency stats, if we want to do history analisis */
|
config.cpu.dependstats = 1;
|
if (config.sim.history && !config.cpu.dependstats) {
|
if (config.sim.verbose)
|
config.cpu.dependstats = 1;
|
fprintf (stderr, "WARNING: dependstats stats must be enabled to do history analisis.\n");
|
if (config.sim.verbose)
|
}
|
fprintf (stderr, "WARNING: dependstats stats must be enabled to do history analisis.\n");
|
#endif
|
}
|
|
#endif
|
#if !FAST_SIM /* We assume we have valid configuration with fsim*/
|
|
/* Debug forces verbose */
|
#if !FAST_SIM /* We assume we have valid configuration with fsim*/
|
if (config.sim.debug && !config.sim.verbose) {
|
/* Debug forces verbose */
|
config.sim.verbose = 1;
|
if (config.sim.debug && !config.sim.verbose) {
|
fprintf (stderr, "WARNING: verbose turned on.\n");
|
config.sim.verbose = 1;
|
}
|
fprintf (stderr, "WARNING: verbose turned on.\n");
|
#endif
|
}
|
|
#endif
|
/* Start VAPI before device initialization. */
|
|
if (config.vapi.enabled) {
|
/* Start VAPI before device initialization. */
|
runtime.vapi.enabled = 1;
|
if (config.vapi.enabled) {
|
vapi_init ();
|
runtime.vapi.enabled = 1;
|
if (config.sim.verbose)
|
vapi_init ();
|
PRINTF ("VAPI started, waiting for clients.\n");
|
if (config.sim.verbose)
|
}
|
PRINTF ("VAPI started, waiting for clients.\n");
|
|
}
|
sim_reset ();
|
|
|
sim_reset ();
|
lock_memory_table ();
|
|
|
lock_memory_table ();
|
/* Wait till all test are connected. */
|
|
if (runtime.vapi.enabled) {
|
/* Wait till all test are connected. */
|
int numu = vapi_num_unconnected (0);
|
if (runtime.vapi.enabled) {
|
if (numu) {
|
int numu = vapi_num_unconnected (0);
|
PRINTF ("\nWaiting for VAPI tests with ids:\n");
|
if (numu) {
|
vapi_num_unconnected (1);
|
PRINTF ("\nWaiting for VAPI tests with ids:\n");
|
PRINTF ("\n");
|
vapi_num_unconnected (1);
|
while (numu = vapi_num_unconnected (0)) {
|
PRINTF ("\n");
|
vapi_check ();
|
while (numu = vapi_num_unconnected (0)) {
|
PRINTF ("\rStill waiting for %i VAPI test(s) to connect. ", numu);
|
vapi_check ();
|
usleep (100);
|
PRINTF ("\rStill waiting for %i VAPI test(s) to connect. ", numu);
|
}
|
usleep (100);
|
PRINTF ("\n");
|
}
|
}
|
PRINTF ("\n");
|
PRINTF ("All devices connected \n");
|
}
|
}
|
PRINTF ("All devices connected \n");
|
/* simulator is initialized */
|
}
|
runtime.sim.init = 0;
|
/* simulator is initialized */
|
}
|
runtime.sim.init = 0;
|
|
}
|
/* Display info about various modules */
|
|
void sim_info () {
|
/* Display info about various modules */
|
sprs_status();
|
void sim_info () {
|
PRINTF ("\n");
|
sprs_status();
|
memory_table_status ();
|
PRINTF ("\n");
|
if (config.immu.enabled) itlb_status(-1);
|
memory_table_status ();
|
if (config.dmmu.enabled) dtlb_status(-1);
|
if (config.immu.enabled) itlb_status(-1);
|
if (config.ic.enabled) ic_info();
|
if (config.dmmu.enabled) dtlb_status(-1);
|
if (config.dc.enabled) dc_info();
|
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.bpb.enabled) bpb_info();
|
|
if (config.bpb.btic) btic_info();
|
if (config.mc.enabled) mc_status();
|
|
if (config.nuarts) uart_status();
|
if (config.mc.enabled) mc_status();
|
if (config.ndmas) dma_status();
|
if (config.nuarts) uart_status();
|
if (config.nethernets) eth_status();
|
if (config.ndmas) dma_status();
|
if (config.ngpios) gpio_status();
|
if (config.nethernets) eth_status();
|
if (config.natas) ata_status();
|
if (config.ngpios) gpio_status();
|
kbd_info();
|
if (config.natas) ata_status();
|
}
|
kbd_info();
|
|
}
|
/* Cleanup */
|
|
void sim_done ()
|
/* Cleanup */
|
{
|
void sim_done ()
|
if (config.sim.profile) {
|
{
|
fprintf(runtime.sim.fprof,"-%08X FFFFFFFF\n", runtime.sim.cycles);
|
if (config.sim.profile) {
|
fclose(runtime.sim.fprof);
|
fprintf(runtime.sim.fprof,"-%08X FFFFFFFF\n", runtime.sim.cycles);
|
}
|
fclose(runtime.sim.fprof);
|
|
}
|
if (config.sim.mprofile) fclose(runtime.sim.fmprof);
|
|
if (config.sim.exe_log) fclose(runtime.sim.fexe_log);
|
if (config.sim.mprofile) fclose(runtime.sim.fmprof);
|
if (runtime.vapi.enabled) vapi_done ();
|
if (config.sim.exe_log) fclose(runtime.sim.fexe_log);
|
done_memory_table ();
|
if (runtime.vapi.enabled) vapi_done ();
|
exit(0);
|
done_memory_table ();
|
}
|
exit(0);
|
|
}
|
/* Executes jobs in time queue */
|
|
static inline void do_scheduler ()
|
/* change result if item found in linestr */
|
{
|
static void addr_from_linestr(char *linestr, int index, int *result)
|
void (*func)(int);
|
{
|
int param;
|
char item[20];
|
|
strtoken(linestr, item, index);
|
/* Execute all jobs till now */
|
if (strlen(item))
|
do {
|
{
|
func = SCHED_PEEK().func;
|
if (item[0] == '_')
|
param = SCHED_PEEK().param;
|
*result = eval_label(item);
|
SCHED_REMOVE();
|
else
|
func (param);
|
*result = strtoul(item, NULL, 0);
|
} while (runtime.sim.cycles >= SCHED_PEEK().time);
|
};
|
}
|
};
|
|
|
/* Main function */
|
/* Executes jobs in time queue */
|
int main(argc, argv)
|
static inline void do_scheduler ()
|
int argc;
|
{
|
char *argv[];
|
void (*func)(int);
|
{
|
int param;
|
char *linestr;
|
|
char item1[500], b2[500], prev_str[500] = "";
|
/* Execute all jobs till now */
|
char *redirstr;
|
do {
|
int hush = 0;
|
func = SCHED_PEEK().func;
|
int first_prompt = 1;
|
param = SCHED_PEEK().param;
|
|
SCHED_REMOVE();
|
srand(getpid());
|
func (param);
|
init_defconfig();
|
} while (runtime.sim.cycles >= SCHED_PEEK().time);
|
if (parse_args(argc, argv)) {
|
}
|
PRINTF("Usage: %s [options] <filename>\n", argv[0]);
|
|
PRINTF("Options:\n");
|
/* Main function */
|
PRINTF(" -v version and copyright note\n");
|
int main(argc, argv)
|
PRINTF(" -i enable interactive command prompt\n");
|
int argc;
|
PRINTF(" --nosrv do not launch JTAG proxy server\n"); /* (CZ) */
|
char *argv[];
|
PRINTF(" --srv <n> launch JTAG proxy server on port <n>; [random]\n"); /* (CZ) */
|
{
|
#if !FAST_SIM
|
char *linestr;
|
PRINTF(" -f or --file load script file [sim.cfg]\n");
|
char item1[500], b2[500], prev_str[500] = "";
|
PRINTF(" --enable-profile enable profiling.\n");
|
char *redirstr;
|
PRINTF(" --enable-mprofile enable memory profiling.\n");
|
int hush = 0;
|
#endif
|
int first_prompt = 1;
|
PRINTF(" --output-cfg prints C structure of current\n");
|
|
PRINTF(" configuration to standard output\n");
|
srand(getpid());
|
PRINTF("\nor : %s ", argv[0]);
|
init_defconfig();
|
mp_help ();
|
if (parse_args(argc, argv)) {
|
PRINTF("\nor : %s ", argv[0]);
|
PRINTF("Usage: %s [options] <filename>\n", argv[0]);
|
prof_help ();
|
PRINTF("Options:\n");
|
exit(-1);
|
PRINTF(" -v version and copyright note\n");
|
}
|
PRINTF(" -i enable interactive command prompt\n");
|
|
PRINTF(" --nosrv do not launch JTAG proxy server\n"); /* (CZ) */
|
#ifdef HAVE_LIBREADLINE
|
PRINTF(" --srv <n> launch JTAG proxy server on port <n>; [random]\n"); /* (CZ) */
|
initialize_readline (); /* Bind our completer. */
|
#if !FAST_SIM
|
#endif
|
PRINTF(" -f or --file load script file [sim.cfg]\n");
|
|
PRINTF(" --enable-profile enable profiling.\n");
|
#if !FAST_SIM
|
PRINTF(" --enable-mprofile enable memory profiling.\n");
|
/* Read configuration file. */
|
#endif
|
if (!runtime.sim.script_file_specified)
|
PRINTF(" --output-cfg prints C structure of current\n");
|
read_script_file ("sim.cfg");
|
PRINTF(" configuration to standard output\n");
|
|
PRINTF("\nor : %s ", argv[0]);
|
/* Overide parameters with command line ones */
|
mp_help ();
|
if (runtime.simcmd.profile) config.sim.profile = 1;
|
PRINTF("\nor : %s ", argv[0]);
|
if (runtime.simcmd.mprofile) config.sim.mprofile = 1;
|
prof_help ();
|
|
exit(-1);
|
if (!runtime.sim.script_file_specified && config.sim.verbose)
|
}
|
fprintf (stderr, "WARNING: No config file read, assuming default configuration.\n");
|
|
#else
|
#ifdef HAVE_LIBREADLINE
|
PRINTF ("\n\tNOTE: running fast sim with fixed configuration!\n\n");
|
initialize_readline (); /* Bind our completer. */
|
#endif
|
#endif
|
if (runtime.sim.output_cfg) {
|
|
output_cfg (stdout);
|
#if !FAST_SIM
|
exit (0);
|
/* Read configuration file. */
|
}
|
if (!runtime.sim.script_file_specified)
|
print_config();
|
read_script_file ("sim.cfg");
|
sim_init ();
|
|
signal(SIGINT, ctrl_c);
|
/* Overide parameters with command line ones */
|
|
if (runtime.simcmd.profile) config.sim.profile = 1;
|
while(1) {
|
if (runtime.simcmd.mprofile) config.sim.mprofile = 1;
|
if (runtime.sim.iprompt) {
|
|
if (config.debug.gdb_enabled)
|
if (!runtime.sim.script_file_specified && config.sim.verbose)
|
{
|
fprintf (stderr, "WARNING: No config file read, assuming default configuration.\n");
|
PRINTF ("(sim) ");
|
#else
|
fflush(stdout);
|
PRINTF ("\n\tNOTE: running fast sim with fixed configuration!\n\n");
|
HandleServerSocket(true); /* block & check_stdin = true */
|
#endif
|
}
|
if (runtime.sim.output_cfg) {
|
#ifdef HAVE_LIBREADLINE
|
output_cfg (stdout);
|
/* Must disable readline in new mode. It isn't compatible
|
exit (0);
|
with non blocking environments */
|
}
|
wait_input:
|
print_config();
|
if(!config.debug.gdb_enabled)
|
sim_init ();
|
linestr = readline("(sim) ");
|
signal(SIGINT, ctrl_c);
|
else
|
|
linestr = fgets(b2, sizeof b2, stdin);
|
while(1) {
|
#else
|
if (runtime.sim.iprompt) {
|
if(!config.debug.gdb_enabled)
|
if (config.debug.gdb_enabled)
|
PRINTF ("(sim) ");
|
{
|
wait_input:
|
PRINTF ("(sim) ");
|
linestr = fgets(b2, sizeof b2, stdin);
|
fflush(stdout);
|
#endif
|
HandleServerSocket(true); /* block & check_stdin = true */
|
} else
|
}
|
strcpy(linestr = b2, "run -1 hush");
|
#ifdef HAVE_LIBREADLINE
|
|
/* Must disable readline in new mode. It isn't compatible
|
if (!linestr) {
|
with non blocking environments */
|
usleep (1000);
|
wait_input:
|
goto wait_input;
|
if(!config.debug.gdb_enabled)
|
}
|
linestr = readline("(sim) ");
|
linestr = stripwhite (linestr);
|
else
|
|
linestr = fgets(b2, sizeof b2, stdin);
|
#ifdef HAVE_LIBREADLINE
|
#else
|
/* Readline only works in the old mode */
|
if(!config.debug.gdb_enabled)
|
if(!server_fd)
|
PRINTF ("(sim) ");
|
{
|
wait_input:
|
if (strlen(linestr) == 0) {
|
linestr = fgets(b2, sizeof b2, stdin);
|
char *l = repeat_last_command ();
|
#endif
|
|
} else
|
if (l) {
|
strcpy(linestr = b2, "run -1 hush");
|
free (linestr);
|
|
linestr = l;
|
if (!linestr) {
|
}
|
usleep (1000);
|
}
|
goto wait_input;
|
|
}
|
if (*linestr) {
|
linestr = stripwhite (linestr);
|
add_history (linestr);
|
|
}
|
#ifdef HAVE_LIBREADLINE
|
}
|
/* Readline only works in the old mode */
|
#endif /* HAVE_LIBREADLINE */
|
if(!server_fd)
|
|
{
|
if (redirstr = strstr(linestr, ">")) {
|
if (strlen(linestr) == 0) {
|
*redirstr = '\0';
|
char *l = repeat_last_command ();
|
strtoken(&redirstr[1], item1, 1);
|
|
runtime.sim.fout = fopen(item1, "w+");
|
if (l) {
|
if (!runtime.sim.fout) runtime.sim.fout = stdout;
|
free (linestr);
|
}
|
linestr = l;
|
|
}
|
if (linestr[0] == '\n')
|
}
|
strcpy (linestr, &prev_str[0]);
|
|
else
|
if (*linestr) {
|
strcpy (&prev_str[0], linestr);
|
add_history (linestr);
|
|
}
|
strtoken(linestr, item1, 1);
|
}
|
if (strcmp(item1, "q") == 0) { /* quit */
|
#endif /* HAVE_LIBREADLINE */
|
PRINTF ("\n");
|
|
sim_done ();
|
if (redirstr = strstr(linestr, ">")) {
|
} else
|
*redirstr = '\0';
|
if (strcmp(item1, "help") == 0) /* help */
|
strtoken(&redirstr[1], item1, 1);
|
help();
|
runtime.sim.fout = fopen(item1, "w+");
|
else
|
if (!runtime.sim.fout) runtime.sim.fout = stdout;
|
if (strcmp(item1, "t") == 0) { /* trace */
|
}
|
runtime.sim.cont_run = 1;
|
|
} else
|
if (linestr[0] == '\n')
|
if (strcmp(item1, "dm") == 0) { /* dump memory */
|
strcpy (linestr, &prev_str[0]);
|
char item2[20];
|
else
|
char item3[20];
|
strcpy (&prev_str[0], linestr);
|
static int from = 0, to = 0;
|
|
|
strtoken(linestr, item1, 1);
|
strtoken(linestr, item2, 2);
|
if (strcmp(item1, "q") == 0) { /* quit */
|
strtoken(linestr, item3, 3);
|
PRINTF ("\n");
|
|
sim_done ();
|
if (strlen(item2)) {
|
} else
|
if (item2[0] == '_')
|
if (strcmp(item1, "help") == 0) /* help */
|
from = eval_label(item2);
|
help();
|
else
|
else
|
from = strtoul(item2, NULL, 0);
|
if (strcmp(item1, "t") == 0) { /* trace */
|
to = from + 0x40;
|
runtime.sim.cont_run = 1;
|
}
|
} else
|
if (strlen(item3))
|
if (strcmp(item1, "dm") == 0) { /* dump memory */
|
to = strtoul(item3, NULL, 0);
|
char item2[20];
|
dumpmemory(from, to, 0, 1);
|
char item3[20];
|
PRINTF("\n");
|
static int from = 0, to = 0;
|
} else
|
|
if (strcmp(item1, "dv") == 0) {/* dump memory as verilog*/
|
strtoken(linestr, item2, 2);
|
char item2[20];
|
strtoken(linestr, item3, 3);
|
char item3[20];
|
|
char item4[20];
|
if (strlen(item2)) {
|
static int from = 0, to = 0;
|
if (item2[0] == '_')
|
|
from = eval_label(item2);
|
strtoken(linestr, item2, 2);
|
else
|
strtoken(linestr, item3, 3);
|
from = strtoul(item2, NULL, 0);
|
strtoken(linestr, item4, 4);
|
to = from + 0x40;
|
|
}
|
if (strlen(item2)) {
|
if (strlen(item3))
|
if (item2[0] == '_')
|
to = strtoul(item3, NULL, 0);
|
from = eval_label(item2);
|
dumpmemory(from, to, 0, 1);
|
else
|
PRINTF("\n");
|
from = strtoul(item2, NULL, 0);
|
} else
|
to = from + 0x40;
|
if (strcmp(item1, "dv") == 0) {/* dump memory as verilog*/
|
}
|
char item2[20];
|
if (strlen(item3))
|
char item3[20];
|
to = strtoul(item3, NULL, 0);
|
char item4[20];
|
if (!strlen(item4))
|
static int from = 0, to = 0;
|
strcpy(item4, "or1k_mem");
|
|
dumpverilog(item4, from, to);
|
strtoken(linestr, item2, 2);
|
PRINTF("\n");
|
strtoken(linestr, item3, 3);
|
} else
|
strtoken(linestr, item4, 4);
|
if (strcmp(item1, "dh") == 0) {/* dump memory as hex*/
|
|
char item2[20];
|
if (strlen(item2)) {
|
char item3[20];
|
if (item2[0] == '_')
|
static int from = 0, to = 0;
|
from = eval_label(item2);
|
|
else
|
strtoken(linestr, item2, 2);
|
from = strtoul(item2, NULL, 0);
|
strtoken(linestr, item3, 3);
|
to = from + 0x40;
|
|
}
|
if (strlen(item2)) {
|
if (strlen(item3))
|
if (item2[0] == '_')
|
to = strtoul(item3, NULL, 0);
|
from = eval_label(item2);
|
if (!strlen(item4))
|
else
|
strcpy(item4, "or1k_mem");
|
from = strtoul(item2, NULL, 0);
|
dumpverilog(item4, from, to);
|
to = from + 0x40;
|
PRINTF("\n");
|
}
|
} else
|
if (strlen(item3))
|
if (strcmp(item1, "dh") == 0) {/* dump memory as hex*/
|
to = strtoul(item3, NULL, 0);
|
char item2[20];
|
dumphex(from, to);
|
char item3[20];
|
PRINTF("\n");
|
static int from = 0, to = 0;
|
} else
|
|
if (strcmp(item1, "pm") == 0) { /* patch memory */
|
strtoken(linestr, item2, 2);
|
char item2[20];
|
strtoken(linestr, item3, 3);
|
char item3[20];
|
|
static int addr = 0;
|
if (strlen(item2)) {
|
int breakpoint = 0;
|
if (item2[0] == '_')
|
|
from = eval_label(item2);
|
strtoken(linestr, item2, 2);
|
else
|
strtoken(linestr, item3, 3);
|
from = strtoul(item2, NULL, 0);
|
if (strlen(item2))
|
to = from + 0x40;
|
if (item2[0] == '_')
|
}
|
addr = eval_label(item2);
|
if (strlen(item3))
|
else
|
to = strtoul(item3, NULL, 0);
|
addr = strtoul(item2, NULL, 0);
|
dumphex(from, to);
|
set_mem32(addr, strtoul(item3, NULL, 0), &breakpoint);
|
PRINTF("\n");
|
} else
|
} else
|
if (strcmp(item1, "pr") == 0) { /* patch regs */
|
if (strcmp(item1, "pm") == 0) { /* patch memory */
|
char item2[20];
|
char item2[20];
|
char item3[20];
|
char item3[20];
|
|
static int addr = 0;
|
strtoken(linestr, item2, 2);
|
int breakpoint = 0;
|
strtoken(linestr, item3, 3);
|
|
setsim_reg32(strtoul(item2, NULL,0), strtoul(item3, NULL, 0));
|
strtoken(linestr, item2, 2);
|
} else
|
strtoken(linestr, item3, 3);
|
if (strcmp(item1, "pc") == 0) { /* patch PC */
|
if (strlen(item2))
|
char item2[20];
|
if (item2[0] == '_')
|
|
addr = eval_label(item2);
|
strtoken(linestr, item2, 2);
|
else
|
pc = strtoul(item2, NULL, 0);
|
addr = strtoul(item2, NULL, 0);
|
} else
|
set_mem32(addr, strtoul(item3, NULL, 0), &breakpoint);
|
if (strcmp(item1, "breaks") == 0) { /* print breakpoints */
|
} else
|
print_breakpoints();
|
if (strcmp(item1, "cm") == 0) { /* copy memory 2004-01-20 hpanther*/
|
} else
|
static int from=0, to=0, size=0;
|
if (strcmp(item1, "break") == 0) { /* set/clear breakpoint */
|
int i;
|
char item2[20];
|
addr_from_linestr(linestr, 2, &from);
|
char *p;
|
addr_from_linestr(linestr, 3, &to);
|
unsigned long addr;
|
addr_from_linestr(linestr, 4, &size);
|
strtoken(linestr, item2, 2);
|
for(i=0; i<size; i+=4)
|
addr = strtoul(item2, &p, 0);
|
setsim_mem32(to+i, evalsim_mem32(from+i));
|
if (*p) {
|
} else
|
struct label_entry *l = find_label (item2);
|
if (strcmp(item1, "pr") == 0) { /* patch regs */
|
if (l) {
|
char item2[20];
|
addr = l->addr;
|
char item3[20];
|
} else addr = 0xffffffff;
|
|
}
|
strtoken(linestr, item2, 2);
|
if (addr != 0xffffffff) set_insnbrkpoint(addr);
|
strtoken(linestr, item3, 3);
|
else PRINTF ("'%s' is invalid address!\n");
|
setsim_reg32(strtoul(item2, NULL,0), strtoul(item3, NULL, 0));
|
} else
|
} else
|
if (strcmp(item1, "r") == 0) { /* dump regs */
|
if (strcmp(item1, "pc") == 0) { /* patch PC */
|
dumpreg();
|
char item2[20];
|
} else
|
|
if (strcmp(item1, "de") == 0) { /* reset simulator */
|
strtoken(linestr, item2, 2);
|
char item2[20];
|
pc = strtoul(item2, NULL, 0);
|
char item3[20];
|
} else
|
static int from = 0, to = 0;
|
if (strcmp(item1, "breaks") == 0) { /* print breakpoints */
|
|
print_breakpoints();
|
strtoken(linestr, item2, 2);
|
} else
|
strtoken(linestr, item3, 3);
|
if (strcmp(item1, "break") == 0) { /* set/clear breakpoint */
|
|
char item2[20];
|
if (strlen(item2)) {
|
char *p;
|
if (item2[0] == '_')
|
unsigned long addr;
|
from = eval_label(item2);
|
strtoken(linestr, item2, 2);
|
else
|
addr = strtoul(item2, &p, 0);
|
from = strtoul(item2, NULL, 0);
|
if (*p) {
|
to = from + 0x40;
|
struct label_entry *l = find_label (item2);
|
}
|
if (l) {
|
if (strlen(item3))
|
addr = l->addr;
|
to = strtoul(item3, NULL, 0);
|
} else addr = 0xffffffff;
|
debugmem(from, to);
|
}
|
PRINTF("\n");
|
if (addr != 0xffffffff) set_insnbrkpoint(addr);
|
} else
|
else PRINTF ("'%s' is invalid address!\n");
|
if (strcmp(item1, "reset") == 0) { /* reset simulator */
|
} else
|
sim_reset();
|
if (strcmp(item1, "r") == 0) { /* dump regs */
|
} else
|
dumpreg();
|
#if !FAST_SIM
|
} else
|
if (strcmp(item1, "debug") == 0) { /* debug mode */
|
if (strcmp(item1, "de") == 0) { /* reset simulator */
|
config.sim.debug ^= 1;
|
char item2[20];
|
} else
|
char item3[20];
|
#endif
|
static int from = 0, to = 0;
|
if (strcmp(item1, "hist") == 0) { /* dump history */
|
|
int i;
|
strtoken(linestr, item2, 2);
|
for(i = HISTEXEC_LEN; i; i--)
|
strtoken(linestr, item3, 3);
|
dumpmemory(histexec[i - 1], histexec[i - 1] + 4, 1, 1);
|
|
PRINTF("\n");
|
if (strlen(item2)) {
|
} else
|
if (item2[0] == '_')
|
if (strcmp(item1, "run") == 0) { /* run */
|
from = eval_label(item2);
|
char item2[20];
|
else
|
char item3[20];
|
from = strtoul(item2, NULL, 0);
|
|
to = from + 0x40;
|
strtoken(linestr, item2, 2);
|
}
|
strtoken(linestr, item3, 3);
|
if (strlen(item3))
|
if (strcmp(item3, "hush") == 0)
|
to = strtoul(item3, NULL, 0);
|
hush = 1;
|
debugmem(from, to);
|
else
|
PRINTF("\n");
|
hush = 0;
|
} else
|
runtime.sim.cont_run = strtol(item2, NULL, 0);
|
if (strcmp(item1, "reset") == 0) { /* reset simulator */
|
} else
|
sim_reset();
|
if(!strcmp(item1, "stall")) { /* Added by CZ 210801 */
|
} else
|
set_stall_state (1);
|
#if !FAST_SIM
|
runtime.sim.iprompt = 0;
|
if (strcmp(item1, "debug") == 0) { /* debug mode */
|
runtime.sim.cont_run = -1;
|
config.sim.debug ^= 1;
|
hush = 1;
|
} else
|
} else
|
#endif
|
if (strcmp(item1, "stats") == 0) { /* stats */
|
if (strcmp(item1, "hist") == 0) { /* dump history */
|
char item2[20];
|
int i;
|
int i = 0;
|
for(i = HISTEXEC_LEN; i; i--)
|
|
dumpmemory(histexec[i - 1], histexec[i - 1] + 4, 1, 1);
|
strtoken(linestr, item2, 2);
|
PRINTF("\n");
|
if (strcmp(item2, "clear") == 0) {
|
} else
|
initstats();
|
if (strcmp(item1, "run") == 0) { /* run */
|
PRINTF("Cleared.\n");
|
char item2[20];
|
} else {
|
char item3[20];
|
i = strtoul(item2, NULL, 0);
|
|
printstats(i);
|
strtoken(linestr, item2, 2);
|
}
|
strtoken(linestr, item3, 3);
|
} else
|
if (strcmp(item3, "hush") == 0)
|
if (strcmp(item1, "info") == 0) /* configuration info */
|
hush = 1;
|
sim_info ();
|
else
|
else
|
hush = 0;
|
#if !FAST_SIM
|
runtime.sim.cont_run = strtol(item2, NULL, 0);
|
if (strcmp (item1, "profiler") == 0) { /* run profiler utility */
|
} else
|
char *argv[10];
|
if(!strcmp(item1, "stall")) { /* Added by CZ 210801 */
|
int argc = tokenize_line (linestr, argv, 10);
|
set_stall_state (1);
|
main_profiler (argc, argv);
|
runtime.sim.iprompt = 0;
|
} else
|
runtime.sim.cont_run = -1;
|
if (strcmp (item1, "mprofiler") == 0) { /* run mprofiler utility */
|
hush = 1;
|
char *argv[10];
|
} else
|
int argc = tokenize_line (linestr, argv, 10);
|
if (strcmp(item1, "stats") == 0) { /* stats */
|
main_mprofiler (argc, argv);
|
char item2[20];
|
} else
|
int i = 0;
|
if (strcmp (item1, "cuc") == 0) { /* run Custom Unit Compiler */
|
|
main_cuc (runtime.sim.filename);
|
strtoken(linestr, item2, 2);
|
} else
|
if (strcmp(item2, "clear") == 0) {
|
if (strcmp(item1, "set") == 0) { /* configuration info */
|
initstats();
|
char *s = linestr;
|
PRINTF("Cleared.\n");
|
int i;
|
} else {
|
extern section;
|
i = strtoul(item2, NULL, 0);
|
extern struct section sections[];
|
printstats(i);
|
while (*s != ' ' && *s) s++;
|
}
|
set_config_command (s);
|
} else
|
} else
|
if (strcmp(item1, "info") == 0) /* configuration info */
|
#endif /* !FAST_SIM */
|
sim_info ();
|
PRINTF("%s: Unknown command.\n", linestr);
|
else
|
|
#if !FAST_SIM
|
{ /* Needed by execution */
|
if (strcmp (item1, "profiler") == 0) { /* run profiler utility */
|
extern int do_stats;
|
char *argv[10];
|
do_stats = config.cpu.dependstats || config.cpu.superscalar || config.cpu.dependstats
|
int argc = tokenize_line (linestr, argv, 10);
|
|| config.sim.history || config.sim.exe_log;
|
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;
|
|
int i;
|
|
extern section;
|
|
extern struct section sections[];
|
|
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
|
|
|| config.sim.history || config.sim.exe_log;
|
|
}
|
|
|
|
/* MM: 'run -1' means endless execution. */
|
|
while(runtime.sim.cont_run) {
|
|
IFF (config.debug.enabled) {
|
|
du_clock(); // reset watchpoints etc.
|
|
if (runtime.cpu.stalled) {
|
|
if(config.debug.gdb_enabled) {
|
|
BlockJTAG();
|
|
HandleServerSocket(false);
|
|
} else {
|
|
fprintf (stderr, "WARNING: CPU stalled and gdb connection not enabled.");
|
|
runtime.sim.cont_run = 0;
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
/* MM: 'run -1' means endless execution. */
|
/* Each cycle has counter of mem_cycles; this value is joined with cycles
|
while(runtime.sim.cont_run) {
|
|
IFF (config.debug.enabled) {
|
|
if (runtime.cpu.stalled) {
|
|
if(config.debug.gdb_enabled) {
|
|
BlockJTAG();
|
|
HandleServerSocket(false);
|
|
} else {
|
|
fprintf (stderr, "WARNING: CPU stalled and gdb connection not enabled.");
|
|
runtime.sim.cont_run = 0;
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
|
/* Each cycle has counter of mem_cycles; this value is joined with cycles
|
|
at the end of the cycle; no sim originated memory accesses should be
|
at the end of the cycle; no sim originated memory accesses should be
|
performed inbetween. */
|
performed inbetween. */
|
runtime.sim.mem_cycles = 0;
|
runtime.sim.mem_cycles = 0;
|
if (!config.pm.enabled || !testsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) {
|
if (!config.pm.enabled || !testsprbits(SPR_PMR, SPR_PMR_DME | SPR_PMR_SME)) {
|
if (runtime.sim.cont_run > 0) runtime.sim.cont_run--;
|
if (runtime.sim.cont_run > 0) runtime.sim.cont_run--;
|
pic_clock ();
|
pic_clock ();
|
if (cpu_clock ()) break;
|
if (cpu_clock ()) break;
|
if (config.dc.enabled) dc_clock();
|
if (config.dc.enabled) dc_clock();
|
if (config.ic.enabled) ic_clock();
|
if (config.ic.enabled) ic_clock();
|
}
|
}
|
|
|
if (config.dmas) dma_clock();
|
if (config.dmas) dma_clock();
|
if (config.ethernets) eth_clock();
|
if (config.ethernets) eth_clock();
|
if (config.ngpios) gpio_clock();
|
if (config.ngpios) gpio_clock();
|
if (config.vapi.enabled && runtime.vapi.enabled) vapi_check();
|
if (config.vapi.enabled && runtime.vapi.enabled) vapi_check();
|
if (config.debug.gdb_enabled) HandleServerSocket(false); /* block & check_stdin = false */
|
if (config.debug.gdb_enabled) HandleServerSocket(false); /* block & check_stdin = false */
|
IFF(config.debug.enabled)
|
IFF(config.debug.enabled)
|
if (testsprbits(SPR_DMR1, SPR_DMR1_ST)) set_stall_state (1);
|
if (testsprbits(SPR_DMR1, SPR_DMR1_ST)) set_stall_state (1);
|
|
|
runtime.sim.cycles += runtime.sim.mem_cycles;
|
runtime.sim.cycles += runtime.sim.mem_cycles;
|
if (runtime.sim.cycles >= SCHED_PEEK().time) do_scheduler ();
|
if (runtime.sim.cycles >= SCHED_PEEK().time) do_scheduler ();
|
if (!hush) dumpreg();
|
if (!hush) dumpreg();
|
}
|
}
|
hush = 0;
|
hush = 0;
|
fflush(stdout);
|
fflush(stdout);
|
runtime.sim.fout = 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 ();
|
|
|
if (!runtime.sim.iprompt) /* non-interactive quit */
|
/* Tell the GNU readline library how to complete. We want to try to complete
|
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
|
on command names if this is the first word in the line, or on filenames
|
if not. */
|
if not. */
|
void initialize_readline ()
|
void initialize_readline ()
|
{
|
{
|
/* Allow conditional parsing of the ~/.inputrc file. */
|
/* Allow conditional parsing of the ~/.inputrc file. */
|
rl_readline_name = "or1ksim";
|
rl_readline_name = "or1ksim";
|
|
|
/* Tell the completer that we want a crack first. */
|
/* Tell the completer that we want a crack first. */
|
rl_attempted_completion_function = (CPPFunction *)sim_completion;
|
rl_attempted_completion_function = (CPPFunction *)sim_completion;
|
}
|
}
|
|
|
/* Attempt to complete on the contents of TEXT. START and END bound the
|
/* 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
|
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
|
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,
|
in case we want to do some simple parsing. Return the array of matches,
|
or NULL if there aren't any. */
|
or NULL if there aren't any. */
|
char **
|
char **
|
sim_completion (text, start, end)
|
sim_completion (text, start, end)
|
char *text;
|
char *text;
|
int start, end;
|
int start, end;
|
{
|
{
|
char **matches;
|
char **matches;
|
|
|
matches = (char **)NULL;
|
matches = (char **)NULL;
|
|
|
/* If this word is at the start of the line, then it is a command
|
/* 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
|
to complete. Otherwise it is the name of a file in the current
|
directory. */
|
directory. */
|
if (start == 0)
|
if (start == 0)
|
matches = completion_matches (text, command_generator);
|
matches = completion_matches (text, command_generator);
|
|
|
return (matches);
|
return (matches);
|
}
|
}
|
|
|
/* Generator function for command completion. STATE lets us know whether
|
/* Generator function for command completion. STATE lets us know whether
|
to start from scratch; without any state (i.e. STATE == 0), then we
|
to start from scratch; without any state (i.e. STATE == 0), then we
|
start at the top of the list. */
|
start at the top of the list. */
|
char *
|
char *
|
command_generator (text, state)
|
command_generator (text, state)
|
char *text;
|
char *text;
|
int state;
|
int state;
|
{
|
{
|
static int list_index, len;
|
static int list_index, len;
|
char *name;
|
char *name;
|
|
|
/* If this is a new word to complete, initialize now. This includes
|
/* If this is a new word to complete, initialize now. This includes
|
saving the length of TEXT for efficiency, and initializing the index
|
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 );
|
|
}
|
|
}
|
|
|
|
No newline at end of file
|
No newline at end of file
|
|
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 );
|
|
}
|
|
}
|
|
|
No newline at end of file
|
No newline at end of file
|