1/* Generic simulator halt/restart. 2 Copyright (C) 1997, 1998, 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 <stdio.h> 22 23#include "sim-main.h" 24#include "sim-assert.h" 25 26/* Get the run state. 27 REASON/SIGRC are the values returned by sim_stop_reason. 28 ??? Should each cpu have its own copy? */ 29 30void 31sim_engine_get_run_state (SIM_DESC sd, enum sim_stop *reason, int *sigrc) 32{ 33 sim_engine *engine = STATE_ENGINE (sd); 34 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 35 *reason = engine->reason; 36 *sigrc = engine->sigrc; 37} 38 39/* Set the run state to REASON/SIGRC. 40 REASON/SIGRC are the values returned by sim_stop_reason. 41 ??? Should each cpu have its own copy? */ 42 43void 44sim_engine_set_run_state (SIM_DESC sd, enum sim_stop reason, int sigrc) 45{ 46 sim_engine *engine = STATE_ENGINE (sd); 47 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 48 engine->reason = reason; 49 engine->sigrc = sigrc; 50} 51 52/* Generic halt */ 53 54void 55sim_engine_halt (SIM_DESC sd, 56 sim_cpu *last_cpu, 57 sim_cpu *next_cpu, /* NULL - use default */ 58 sim_cia cia, 59 enum sim_stop reason, 60 int sigrc) 61{ 62 sim_engine *engine = STATE_ENGINE (sd); 63 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 64 if (engine->jmpbuf != NULL) 65 { 66 jmp_buf *halt_buf = engine->jmpbuf; 67 engine->last_cpu = last_cpu; 68 engine->next_cpu = next_cpu; 69 engine->reason = reason; 70 engine->sigrc = sigrc; 71 72 SIM_ENGINE_HALT_HOOK (sd, last_cpu, cia); 73 74#ifdef SIM_CPU_EXCEPTION_SUSPEND 75 if (last_cpu != NULL && reason != sim_exited) 76 SIM_CPU_EXCEPTION_SUSPEND (sd, last_cpu, sim_signal_to_host (sd, sigrc)); 77#endif 78 79 longjmp (*halt_buf, sim_engine_halt_jmpval); 80 } 81 else 82 { 83 sim_io_error (sd, "sim_halt - bad long jump"); 84 abort (); 85 } 86} 87 88 89/* Generic restart */ 90 91void 92sim_engine_restart (SIM_DESC sd, 93 sim_cpu *last_cpu, 94 sim_cpu *next_cpu, 95 sim_cia cia) 96{ 97 sim_engine *engine = STATE_ENGINE (sd); 98 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 99 if (engine->jmpbuf != NULL) 100 { 101 jmp_buf *halt_buf = engine->jmpbuf; 102 engine->last_cpu = last_cpu; 103 engine->next_cpu = next_cpu; 104 SIM_ENGINE_RESTART_HOOK (sd, last_cpu, cia); 105 longjmp (*halt_buf, sim_engine_restart_jmpval); 106 } 107 else 108 sim_io_error (sd, "sim_restart - bad long jump"); 109} 110 111 112/* Generic error code */ 113 114void 115sim_engine_vabort (SIM_DESC sd, 116 sim_cpu *cpu, 117 sim_cia cia, 118 const char *fmt, 119 va_list ap) 120{ 121 ASSERT (sd == NULL || STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 122 if (sd == NULL) 123 { 124 vfprintf (stderr, fmt, ap); 125 fprintf (stderr, "\nQuit\n"); 126 abort (); 127 } 128 else if (STATE_ENGINE (sd)->jmpbuf == NULL) 129 { 130 sim_io_evprintf (sd, fmt, ap); 131 sim_io_eprintf (sd, "\n"); 132 sim_io_error (sd, "Quit Simulator"); 133 abort (); 134 } 135 else 136 { 137 sim_io_evprintf (sd, fmt, ap); 138 sim_io_eprintf (sd, "\n"); 139 sim_engine_halt (sd, cpu, NULL, cia, sim_stopped, SIM_SIGABRT); 140 } 141} 142 143void 144sim_engine_abort (SIM_DESC sd, 145 sim_cpu *cpu, 146 sim_cia cia, 147 const char *fmt, 148 ...) 149{ 150 va_list ap; 151 ASSERT (sd == NULL || STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 152 va_start(ap, fmt); 153 sim_engine_vabort (sd, cpu, cia, fmt, ap); 154 va_end (ap); 155} 156 157 158/* Generic next/last cpu */ 159 160int 161sim_engine_last_cpu_nr (SIM_DESC sd) 162{ 163 sim_engine *engine = STATE_ENGINE (sd); 164 if (engine->last_cpu != NULL) 165 return engine->last_cpu - STATE_CPU (sd, 0); 166 else 167 return MAX_NR_PROCESSORS; 168} 169 170int 171sim_engine_next_cpu_nr (SIM_DESC sd) 172{ 173 sim_engine *engine = STATE_ENGINE (sd); 174 if (engine->next_cpu != NULL) 175 return engine->next_cpu - STATE_CPU (sd, 0); 176 else 177 return sim_engine_last_cpu_nr (sd) + 1; 178} 179 180int 181sim_engine_nr_cpus (SIM_DESC sd) 182{ 183 sim_engine *engine = STATE_ENGINE (sd); 184 return engine->nr_cpus; 185} 186 187 188 189 190/* Initialization */ 191 192static SIM_RC 193sim_engine_init (SIM_DESC sd) 194{ 195 /* initialize the start/stop/resume engine */ 196 sim_engine *engine = STATE_ENGINE (sd); 197 engine->jmpbuf = NULL; 198 engine->last_cpu = NULL; 199 engine->next_cpu = NULL; 200 engine->nr_cpus = MAX_NR_PROCESSORS; 201 engine->reason = sim_running; 202 engine->sigrc = 0; 203 engine->stepper = NULL; /* sim_events_init will clean it up */ 204 return SIM_RC_OK; 205} 206 207 208SIM_RC 209sim_engine_install (SIM_DESC sd) 210{ 211 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 212 sim_module_add_init_fn (sd, sim_engine_init); 213 return SIM_RC_OK; 214} 215