diff options
Diffstat (limited to 'sim/ppc')
-rw-r--r-- | sim/ppc/ChangeLog | 8 | ||||
-rw-r--r-- | sim/ppc/psim.c | 132 | ||||
-rw-r--r-- | sim/ppc/sim_calls.c | 84 |
3 files changed, 162 insertions, 62 deletions
diff --git a/sim/ppc/ChangeLog b/sim/ppc/ChangeLog index a91f38708e8..9c35194d424 100644 --- a/sim/ppc/ChangeLog +++ b/sim/ppc/ChangeLog @@ -1,3 +1,11 @@ +Thu Apr 17 03:28:03 1997 Doug Evans <dje@canuck.cygnus.com> + + * psim.c (psim_options): Ignore -E option (sets endianness). + * sim_calls.c: #include bfd.h. + (entry_point): New static local. + (sim_load): Return SIM_RC. New arg abfd. Set start address from bfd. + (sim_create_inferior): Return SIM_RC. Delete arg start_address. + Tue Apr 15 14:57:18 1997 Ian Lance Taylor <ian@cygnus.com> * Makefile.in (INSTALL): Set to @INSTALL@. diff --git a/sim/ppc/psim.c b/sim/ppc/psim.c index c2d3a6067b4..88ba9bfe4b0 100644 --- a/sim/ppc/psim.c +++ b/sim/ppc/psim.c @@ -147,8 +147,16 @@ psim_usage(int verbose) printf_filtered("The following are valid <psim-option>s:\n"); printf_filtered("\n"); - printf_filtered("\t-i Print instruction counting statistics\n"); - if (verbose) { printf_filtered("\n"); } + printf_filtered("\t-c <count> Limit the simulation to <count> iterations\n"); + if (verbose) { + printf_filtered("\n"); + } + + printf_filtered("\t-i or -i2 Print instruction counting statistics\n"); + if (verbose) { + printf_filtered("\t Specify -i2 for a more detailed display\n"); + printf_filtered("\n"); + } printf_filtered("\t-I Print execution unit statistics\n"); if (verbose) { printf_filtered("\n"); } @@ -221,8 +229,12 @@ psim_options(device *root, psim_usage(0); error (""); break; + case 'c': + param = find_arg("Missing <count> option for -c (max-iterations)\n", &argp, argv); + tree_parse(root, "/openprom/options/max-iterations %s", param); + break; case 'e': - param = find_arg("Missing <emul> option for -e\n", &argp, argv); + param = find_arg("Missing <emul> option for -e (os-emul)\n", &argp, argv); tree_parse(root, "/openprom/options/os-emul %s", param); break; case 'f': @@ -237,7 +249,13 @@ psim_options(device *root, psim_usage(2); break; case 'i': - tree_parse(root, "/openprom/trace/print-info 1"); + if (isdigit(p[1])) { + tree_parse(root, "/openprom/trace/print-info %c", p[1]); + p++; + } + else { + tree_parse(root, "/openprom/trace/print-info 1"); + } break; case 'I': tree_parse(root, "/openprom/trace/print-info 2"); @@ -245,11 +263,11 @@ psim_options(device *root, MODEL_ISSUE_PROCESS); break; case 'm': - param = find_arg("Missing <model> option for -m\n", &argp, argv); + param = find_arg("Missing <model> option for -m (model)\n", &argp, argv); tree_parse(root, "/openprom/options/model \"%s", param); break; case 'n': - param = find_arg("Missing <nr-smp> option for -n\n", &argp, argv); + param = find_arg("Missing <nr-smp> option for -n (smp)\n", &argp, argv); tree_parse(root, "/openprom/options/smp %s", param); break; case 'o': @@ -257,17 +275,21 @@ psim_options(device *root, current = tree_parse(current, "%s", param); break; case 'r': - param = find_arg("Missing <ram-size> option for -r\n", &argp, argv); + param = find_arg("Missing <ram-size> option for -r (oea-memory-size)\n", &argp, argv); tree_parse(root, "/openprom/options/oea-memory-size %s", param); break; case 't': - param = find_arg("Missing <trace> option for -t\n", &argp, argv); + param = find_arg("Missing <trace> option for -t (trace/*)\n", &argp, argv); if (param[0] == '!') tree_parse(root, "/openprom/trace/%s 0", param+1); else tree_parse(root, "/openprom/trace/%s 1", param); break; + case 'E': + /* endian spec, ignored for now */ + ++p; + break; } p += 1; } @@ -466,6 +488,8 @@ INLINE_PSIM\ psim_restart(psim *system, int current_cpu) { + ASSERT(current_cpu >= 0 && current_cpu < system->nr_cpus); + ASSERT(system->path_to_restart != NULL); system->last_cpu = current_cpu; longjmp(*(jmp_buf*)(system->path_to_restart), current_cpu + 1); } @@ -478,13 +502,21 @@ psim_halt(psim *system, stop_reason reason, int signal) { - ASSERT(current_cpu >= 0 && current_cpu < system->nr_cpus); + ASSERT(current_cpu >= 0 && current_cpu <= system->nr_cpus); + ASSERT(system->path_to_halt != NULL); system->last_cpu = current_cpu; - system->halt_status.cpu_nr = current_cpu; system->halt_status.reason = reason; system->halt_status.signal = signal; - system->halt_status.program_counter = - cpu_get_program_counter(system->processors[current_cpu]); + if (current_cpu == system->nr_cpus) { + system->halt_status.cpu_nr = 0; + system->halt_status.program_counter = + cpu_get_program_counter(system->processors[0]); + } + else { + system->halt_status.cpu_nr = current_cpu; + system->halt_status.program_counter = + cpu_get_program_counter(system->processors[current_cpu]); + } longjmp(*(jmp_buf*)(system->path_to_halt), current_cpu + 1); } @@ -540,6 +572,18 @@ psim_event_queue(psim *system) +STATIC_INLINE_PSIM\ +(void) +psim_max_iterations_exceeded(void *data) +{ + psim *system = data; + psim_halt(system, + system->nr_cpus, /* halted during an event */ + was_signalled, + -1); +} + + INLINE_PSIM\ (void) psim_init(psim *system) @@ -552,6 +596,17 @@ psim_init(psim *system) /* trash any pending events */ event_queue_init(system->events); + /* if needed, schedule a halt event. FIXME - In the future this + will be replaced by a more generic change to psim_command(). A + new command `schedule NNN halt' being added. */ + if (tree_find_property(system->devices, "/openprom/options/max-iterations")) { + event_queue_schedule(system->events, + tree_find_integer_property(system->devices, + "/openprom/options/max-iterations") - 2, + psim_max_iterations_exceeded, + system); + } + /* scrub all the cpus */ for (cpu_nr = 0; cpu_nr < system->nr_cpus; cpu_nr++) cpu_init(system->processors[cpu_nr]); @@ -569,8 +624,8 @@ psim_init(psim *system) cpu_page_tlb_invalidate_all(processor); } - /* force loop to start with first cpu (after processing events) */ - system->last_cpu = system->nr_cpus - 1; + /* force loop to start with first cpu */ + system->last_cpu = -1; } INLINE_PSIM\ @@ -644,10 +699,15 @@ psim_read_register(psim *system, cpu *processor; /* find our processor */ - if (which_cpu == MAX_NR_PROCESSORS) - which_cpu = system->last_cpu; - if (which_cpu < 0 || which_cpu >= system->nr_cpus) - error("psim_read_register() - invalid processor %d\n", which_cpu); + if (which_cpu == MAX_NR_PROCESSORS) { + if (system->last_cpu == system->nr_cpus + || system->last_cpu == -1) + which_cpu = 0; + else + which_cpu = system->last_cpu; + } + ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus); + processor = system->processors[which_cpu]; /* find the register description */ @@ -751,17 +811,20 @@ psim_write_register(psim *system, char cooked_buf[sizeof(unsigned_8)]; /* find our processor */ - if (which_cpu == MAX_NR_PROCESSORS) - which_cpu = system->last_cpu; + if (which_cpu == MAX_NR_PROCESSORS) { + if (system->last_cpu == system->nr_cpus + || system->last_cpu == -1) + which_cpu = 0; + else + which_cpu = system->last_cpu; + } if (which_cpu == -1) { int i; for (i = 0; i < system->nr_cpus; i++) psim_write_register(system, i, buf, reg, mode); return; } - else if (which_cpu < 0 || which_cpu >= system->nr_cpus) { - error("psim_read_register() - invalid processor %d\n", which_cpu); - } + ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus); processor = system->processors[which_cpu]; @@ -844,10 +907,13 @@ psim_read_memory(psim *system, unsigned nr_bytes) { cpu *processor; - if (which_cpu == MAX_NR_PROCESSORS) - which_cpu = system->last_cpu; - if (which_cpu < 0 || which_cpu >= system->nr_cpus) - error("psim_read_memory() invalid cpu\n"); + if (which_cpu == MAX_NR_PROCESSORS) { + if (system->last_cpu == system->nr_cpus + || system->last_cpu == -1) + which_cpu = 0; + else + which_cpu = system->last_cpu; + } processor = system->processors[which_cpu]; return vm_data_map_read_buffer(cpu_data_map(processor), buffer, vaddr, nr_bytes, @@ -865,10 +931,14 @@ psim_write_memory(psim *system, int violate_read_only_section) { cpu *processor; - if (which_cpu == MAX_NR_PROCESSORS) - which_cpu = system->last_cpu; - if (which_cpu < 0 || which_cpu >= system->nr_cpus) - error("psim_read_memory() invalid cpu\n"); + if (which_cpu == MAX_NR_PROCESSORS) { + if (system->last_cpu == system->nr_cpus + || system->last_cpu == -1) + which_cpu = 0; + else + which_cpu = system->last_cpu; + } + ASSERT(which_cpu >= 0 && which_cpu < system->nr_cpus); processor = system->processors[which_cpu]; return vm_data_map_write_buffer(cpu_data_map(processor), buffer, vaddr, nr_bytes, 1/*violate-read-only*/, diff --git a/sim/ppc/sim_calls.c b/sim/ppc/sim_calls.c index 35a9212d5d2..b9962b8d9ec 100644 --- a/sim/ppc/sim_calls.c +++ b/sim/ppc/sim_calls.c @@ -41,6 +41,7 @@ #endif #include "defs.h" +#include "bfd.h" #include "callback.h" #include "remote-sim.h" @@ -51,32 +52,35 @@ static psim *simulator; static device *root_device; static const char *register_names[] = REGISTER_NAMES; -void -sim_open (char *args) +/* For communication between sim_load and sim_create_inferior. + This can be made to go away, please do. */ +static unsigned_word entry_point; + +SIM_DESC +sim_open (SIM_OPEN_KIND kind, char **argv) { /* Note: The simulation is not created by sim_open() because complete information is not yet available */ /* trace the call */ - TRACE(trace_gdb, ("sim_open(args=%s) called\n", args ? args : "(null)")); + TRACE(trace_gdb, ("sim_open called\n")); if (root_device != NULL) sim_io_printf_filtered("Warning - re-open of simulator leaks memory\n"); root_device = psim_tree(); simulator = NULL; - if (args) { - char **argv = buildargv(args); - psim_options(root_device, argv); - freeargv(argv); - } + psim_options(root_device, argv + 1); if (ppc_trace[trace_opts]) print_options (); + + /* fudge our descriptor for now */ + return (SIM_DESC) 1; } void -sim_close (int quitting) +sim_close (SIM_DESC sd, int quitting) { TRACE(trace_gdb, ("sim_close(quitting=%d) called\n", quitting)); if (ppc_trace[trace_print_info] && simulator != NULL) @@ -84,8 +88,8 @@ sim_close (int quitting) } -int -sim_load (char *prog, int from_tty) +SIM_RC +sim_load (SIM_DESC sd, char *prog, bfd *abfd, int from_tty) { char **argv; TRACE(trace_gdb, ("sim_load(prog=%s, from_tty=%d) called\n", @@ -106,13 +110,32 @@ sim_load (char *prog, int from_tty) /* release the arguments */ freeargv(argv); - /* `I did it my way' */ - return 0; + /* get the start address */ + if (abfd != NULL) + entry_point = bfd_get_start_address (abfd); + else + { + abfd = bfd_openr (argv[0], 0); + if (abfd == NULL) + error ("psim: can't open \"%s\": %s\n", + argv[0], bfd_errmsg (bfd_get_error ())); + if (!bfd_check_format (abfd, bfd_object)) + { + const char *errmsg = bfd_errmsg (bfd_get_error ()); + bfd_close (abfd); + error ("psim: \"%s\" is not an object file: %s\n", + argv[0], errmsg); + } + entry_point = bfd_get_start_address (abfd); + bfd_close (abfd); + } + + return SIM_RC_OK; } void -sim_kill (void) +sim_kill (SIM_DESC sd) { TRACE(trace_gdb, ("sim_kill(void) called\n")); /* do nothing, nothing to do */ @@ -120,7 +143,7 @@ sim_kill (void) int -sim_read (SIM_ADDR mem, unsigned char *buf, int length) +sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length) { int result = psim_read_memory(simulator, MAX_NR_PROCESSORS, buf, mem, length); @@ -131,7 +154,7 @@ sim_read (SIM_ADDR mem, unsigned char *buf, int length) int -sim_write (SIM_ADDR mem, unsigned char *buf, int length) +sim_write (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length) { int result = psim_write_memory(simulator, MAX_NR_PROCESSORS, buf, mem, length, @@ -143,7 +166,7 @@ sim_write (SIM_ADDR mem, unsigned char *buf, int length) void -sim_fetch_register (int regno, unsigned char *buf) +sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf) { if (simulator == NULL) { return; @@ -157,7 +180,7 @@ sim_fetch_register (int regno, unsigned char *buf) void -sim_store_register (int regno, unsigned char *buf) +sim_store_register (SIM_DESC sd, int regno, unsigned char *buf) { if (simulator == NULL) return; @@ -170,33 +193,32 @@ sim_store_register (int regno, unsigned char *buf) void -sim_info (int verbose) +sim_info (SIM_DESC sd, int verbose) { TRACE(trace_gdb, ("sim_info(verbose=%d) called\n", verbose)); psim_print_info (simulator, verbose); } -void -sim_create_inferior (SIM_ADDR start_address, char **argv, char **envp) +SIM_RC +sim_create_inferior (SIM_DESC sd, char **argv, char **envp) { - unsigned_word entry_point = start_address; - TRACE(trace_gdb, ("sim_create_inferior(start_address=0x%x, ...)\n", - start_address)); + entry_point)); psim_init(simulator); psim_stack(simulator, argv, envp); psim_write_register(simulator, -1 /* all start at same PC */, &entry_point, "pc", cooked_transfer); + return SIM_RC_OK; } static volatile int sim_should_run; void -sim_stop_reason (enum sim_stop *reason, int *sigrc) +sim_stop_reason (SIM_DESC sd, enum sim_stop *reason, int *sigrc) { psim_status status = psim_get_status(simulator); @@ -244,14 +266,14 @@ sim_stop_reason (enum sim_stop *reason, int *sigrc) /* Run (or resume) the program. */ -static void -sim_ctrl_c() +static RETSIGTYPE +sim_ctrl_c(int sig) { sim_should_run = 0; } void -sim_resume (int step, int siggnal) +sim_resume (SIM_DESC sd, int step, int siggnal) { TRACE(trace_gdb, ("sim_resume(step=%d, siggnal=%d)\n", step, siggnal)); @@ -265,7 +287,7 @@ sim_resume (int step, int siggnal) } else { - void (*prev) (); + RETSIGTYPE (*prev) (); prev = signal(SIGINT, sim_ctrl_c); sim_should_run = 1; @@ -275,7 +297,7 @@ sim_resume (int step, int siggnal) } void -sim_do_command (char *cmd) +sim_do_command (SIM_DESC sd, char *cmd) { TRACE(trace_gdb, ("sim_do_commands(cmd=%s) called\n", cmd ? cmd : "(null)")); @@ -384,7 +406,7 @@ sim_io_flush_stdoutput(void) } void -sim_set_callbacks (host_callback *callback) +sim_set_callbacks (SIM_DESC sd, host_callback *callback) { callbacks = callback; TRACE(trace_gdb, ("sim_set_callbacks called\n")); |