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 6 This file is part of GDB, the GNU debugger. 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along 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 30 void 31 sim_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 43 void 44 sim_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 54 void 55 sim_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 91 void 92 sim_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 114 void 115 sim_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 143 void 144 sim_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 160 int 161 sim_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 170 int 171 sim_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 180 int 181 sim_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 192 static SIM_RC 193 sim_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 208 SIM_RC 209 sim_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