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