1/* Generic simulator resume. 2 Copyright (C) 1997, 2007 Free Software Foundation, Inc. 3 Contributed by Cygnus Support. 4 5This file is part of GDB, the GNU debugger. 6 7This program is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 3 of the License, or 10(at your option) any later version. 11 12This program is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20#include "sim-main.h" 21#include "sim-assert.h" 22 23/* Halt the simulator after just one instruction */ 24 25static void 26has_stepped (SIM_DESC sd, 27 void *data) 28{ 29 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 30 sim_engine_halt (sd, NULL, NULL, NULL_CIA, sim_stopped, SIM_SIGTRAP); 31} 32 33 34/* Generic resume - assumes the existance of sim_engine_run */ 35 36void 37sim_resume (SIM_DESC sd, 38 int step, 39 int siggnal) 40{ 41 sim_engine *engine = STATE_ENGINE (sd); 42 jmp_buf buf; 43 int jmpval; 44 45 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 46 47 /* we only want to be single stepping the simulator once */ 48 if (engine->stepper != NULL) 49 { 50 sim_events_deschedule (sd, engine->stepper); 51 engine->stepper = NULL; 52 } 53 if (step) 54 engine->stepper = sim_events_schedule (sd, 1, has_stepped, sd); 55 56 sim_module_resume (sd); 57 58 /* run/resume the simulator */ 59 engine->jmpbuf = &buf; 60 jmpval = setjmp (buf); 61 if (jmpval == sim_engine_start_jmpval 62 || jmpval == sim_engine_restart_jmpval) 63 { 64 int last_cpu_nr = sim_engine_last_cpu_nr (sd); 65 int next_cpu_nr = sim_engine_next_cpu_nr (sd); 66 int nr_cpus = sim_engine_nr_cpus (sd); 67 int sig_to_deliver; 68 69 sim_events_preprocess (sd, last_cpu_nr >= nr_cpus, next_cpu_nr >= nr_cpus); 70 if (next_cpu_nr >= nr_cpus) 71 next_cpu_nr = 0; 72 73 /* Only deliver the SIGGNAL [sic] the first time through - don't 74 re-deliver any SIGGNAL during a restart. NOTE: A new local 75 variable is used to avoid problems with the automatic 76 variable ``siggnal'' being trashed by a long jump. */ 77 if (jmpval == sim_engine_start_jmpval) 78 sig_to_deliver = siggnal; 79 else 80 sig_to_deliver = 0; 81 82#ifdef SIM_CPU_EXCEPTION_RESUME 83 { 84 sim_cpu* cpu = STATE_CPU (sd, next_cpu_nr); 85 SIM_CPU_EXCEPTION_RESUME(sd, cpu, sig_to_deliver); 86 } 87#endif 88 89 sim_engine_run (sd, next_cpu_nr, nr_cpus, sig_to_deliver); 90 } 91 engine->jmpbuf = NULL; 92 93 sim_module_suspend (sd); 94} 95