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