1 /* Generic simulator resume. 2 Copyright (C) 1997-2020 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 #include "sim-main.h" 21 #include "sim-assert.h" 22 23 /* Halt the simulator after just one instruction */ 24 25 static void 26 has_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 36 void 37 sim_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