Commit | Line | Data |
---|---|---|
8eab189b MM |
1 | /* This file is part of the program psim. |
2 | ||
3 | Copyright (C) 1994-1995, Andrew Cagney <cagney@highland.com.au> | |
4 | ||
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 2 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program; if not, write to the Free Software | |
17 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
18 | ||
19 | */ | |
20 | ||
21 | ||
22 | #include <signal.h> /* FIXME - should be machine dependant version */ | |
23 | #include <stdarg.h> | |
8eab189b MM |
24 | #include <ctype.h> |
25 | ||
28816f45 | 26 | #include "cpu.h" |
8eab189b | 27 | #include "psim.h" |
28816f45 | 28 | #include "options.h" |
8eab189b | 29 | |
c494cadd MM |
30 | #ifdef HAVE_STDLIB_H |
31 | #include <stdlib.h> | |
32 | #endif | |
33 | ||
34 | #ifdef HAVE_STRING_H | |
35 | #include <string.h> | |
36 | #else | |
37 | #ifdef HAVE_STRINGS_H | |
38 | #include <strings.h> | |
39 | #endif | |
40 | #endif | |
41 | ||
8eab189b MM |
42 | #include "../../gdb/defs.h" |
43 | ||
44 | #include "devices.h" | |
45 | ||
46 | #include "../../gdb/remote-sim.h" | |
f46f3807 | 47 | #include "../../gdb/callback.h" |
8eab189b MM |
48 | |
49 | ||
50 | /* Structures used by the simulator, for gdb just have static structures */ | |
51 | ||
52 | static psim *simulator; | |
8eab189b | 53 | static char *register_names[] = REGISTER_NAMES; |
83d96c6e | 54 | static int print_info = 0; |
8eab189b MM |
55 | |
56 | void | |
57 | sim_open (char *args) | |
58 | { | |
8eab189b MM |
59 | /* trace the call */ |
60 | TRACE(trace_gdb, ("sim_open(args=%s) called\n", args ? args : "(null)")); | |
61 | ||
62 | if (args) { | |
a983c8f0 MM |
63 | char **argv = buildargv(args); |
64 | int argp = 0; | |
65 | int argc; | |
66 | for (argc = 0; argv[argc]; argc++); | |
8eab189b | 67 | |
a983c8f0 MM |
68 | while (argp < argc) { |
69 | if (*argv[argp] != '-') | |
70 | error ("Argument is not an option '%s'", argv[argp]); | |
8eab189b MM |
71 | |
72 | else { | |
73 | /* check arguments -- note, main.c also contains argument processing | |
74 | code for the standalone emulator. */ | |
a983c8f0 MM |
75 | char *p = argv[argp] + 1; |
76 | while (*p != '\0') { | |
8eab189b MM |
77 | switch (*p) { |
78 | default: | |
73c4941b | 79 | printf_filtered("Usage:\n\ttarget sim [ -t <trace-option> ] [-m model] [-i] [-I]\n"); |
a983c8f0 MM |
80 | trace_usage(); |
81 | error (""); | |
8eab189b | 82 | break; |
a983c8f0 | 83 | case 't': |
73c4941b MM |
84 | if (p[1]) |
85 | trace_option(p+1); | |
86 | else { | |
87 | argp += 1; | |
88 | if (argv[argp] == NULL) | |
89 | error("Missing <trace> option for -t\n"); | |
90 | else | |
91 | trace_option(argv[argp]); | |
92 | } | |
8eab189b | 93 | break; |
73c4941b MM |
94 | case 'm': |
95 | if (p[1]) | |
28816f45 | 96 | model_set(p+1); |
73c4941b MM |
97 | else { |
98 | argp += 1; | |
99 | if (argv[argp] == NULL) | |
100 | error("Missing <trace> option for -t\n"); | |
101 | else | |
28816f45 | 102 | model_set(argv[argp]); |
73c4941b MM |
103 | } |
104 | break; | |
105 | case 'i': | |
83d96c6e MM |
106 | print_info = 1; |
107 | break; | |
73c4941b | 108 | case 'I': |
290ad14a | 109 | current_model_issue = MODEL_ISSUE_PROCESS; |
73c4941b MM |
110 | print_info = 2; |
111 | break; | |
8eab189b | 112 | } |
4dcb0cdd | 113 | p += 1; |
8eab189b MM |
114 | } |
115 | } | |
a983c8f0 | 116 | argp += 1; |
8eab189b MM |
117 | } |
118 | } | |
119 | ||
28816f45 MM |
120 | if (ppc_trace[trace_opts]) |
121 | print_options (); | |
122 | ||
8eab189b MM |
123 | /* do something */ |
124 | TRACE(trace_tbd, ("sim_open() - TBD - should parse the arguments\n")); | |
125 | TRACE(trace_tbd, ("sim_open() - TBD - can not create simulator here as do not have description of it\n")); | |
126 | } | |
127 | ||
128 | ||
129 | void | |
130 | sim_close (int quitting) | |
131 | { | |
132 | TRACE(trace_gdb, ("sim_close(quitting=%d) called\n", quitting)); | |
83d96c6e | 133 | if (print_info) |
73c4941b | 134 | psim_print_info (simulator, print_info); |
83d96c6e | 135 | |
8eab189b MM |
136 | /* nothing to do */ |
137 | } | |
138 | ||
139 | ||
140 | int | |
141 | sim_load (char *prog, int from_tty) | |
142 | { | |
a983c8f0 | 143 | char **argv; |
8eab189b MM |
144 | TRACE(trace_gdb, ("sim_load(prog=%s, from_tty=%d) called\n", |
145 | prog, from_tty)); | |
a983c8f0 | 146 | ASSERT(prog != NULL); |
8eab189b | 147 | |
a983c8f0 MM |
148 | /* parse the arguments, assume that the file is argument 0 */ |
149 | argv = buildargv(prog); | |
150 | ASSERT(argv != NULL && argv[0] != NULL); | |
8eab189b MM |
151 | |
152 | /* create the simulator */ | |
153 | TRACE(trace_gdb, ("sim_load() - first time, create the simulator\n")); | |
a983c8f0 | 154 | simulator = psim_create(argv[0]); |
8eab189b MM |
155 | |
156 | /* bring in all the data section */ | |
a983c8f0 | 157 | psim_init(simulator); |
8eab189b | 158 | |
a983c8f0 MM |
159 | /* release the arguments */ |
160 | freeargv(argv); | |
161 | ||
162 | /* `I did it my way' */ | |
8eab189b MM |
163 | return 0; |
164 | } | |
165 | ||
166 | ||
167 | void | |
168 | sim_kill (void) | |
169 | { | |
170 | TRACE(trace_gdb, ("sim_kill(void) called\n")); | |
171 | /* do nothing, nothing to do */ | |
172 | } | |
173 | ||
174 | ||
175 | int | |
176 | sim_read (SIM_ADDR mem, unsigned char *buf, int length) | |
177 | { | |
a983c8f0 MM |
178 | int result = psim_read_memory(simulator, MAX_NR_PROCESSORS, |
179 | buf, mem, length); | |
28816f45 MM |
180 | TRACE(trace_gdb, ("sim_read(mem=0x%lx, buf=0x%lx, length=%d) = %d\n", |
181 | (long)mem, (long)buf, length, result)); | |
a983c8f0 | 182 | return result; |
8eab189b MM |
183 | } |
184 | ||
185 | ||
186 | int | |
187 | sim_write (SIM_ADDR mem, unsigned char *buf, int length) | |
188 | { | |
a983c8f0 MM |
189 | int result = psim_write_memory(simulator, MAX_NR_PROCESSORS, |
190 | buf, mem, length, | |
191 | 1/*violate_ro*/); | |
28816f45 MM |
192 | TRACE(trace_gdb, ("sim_write(mem=0x%lx, buf=0x%lx, length=%d) = %d\n", |
193 | (long)mem, (long)buf, length, result)); | |
a983c8f0 | 194 | return result; |
8eab189b MM |
195 | } |
196 | ||
197 | ||
198 | void | |
199 | sim_fetch_register (int regno, unsigned char *buf) | |
200 | { | |
201 | if (simulator == NULL) { | |
202 | return; | |
203 | } | |
28816f45 MM |
204 | TRACE(trace_gdb, ("sim_fetch_register(regno=%d(%s), buf=0x%lx)\n", |
205 | regno, register_names[regno], (long)buf)); | |
a983c8f0 MM |
206 | psim_read_register(simulator, MAX_NR_PROCESSORS, |
207 | buf, register_names[regno], | |
8eab189b MM |
208 | raw_transfer); |
209 | } | |
210 | ||
211 | ||
212 | void | |
213 | sim_store_register (int regno, unsigned char *buf) | |
214 | { | |
215 | if (simulator == NULL) | |
216 | return; | |
28816f45 MM |
217 | TRACE(trace_gdb, ("sim_store_register(regno=%d(%s), buf=0x%lx)\n", |
218 | regno, register_names[regno], (long)buf)); | |
a983c8f0 MM |
219 | psim_write_register(simulator, MAX_NR_PROCESSORS, |
220 | buf, register_names[regno], | |
8eab189b MM |
221 | raw_transfer); |
222 | } | |
223 | ||
224 | ||
225 | void | |
226 | sim_info (int verbose) | |
227 | { | |
228 | TRACE(trace_gdb, ("sim_info(verbose=%d) called\n", verbose)); | |
83d96c6e | 229 | psim_print_info (simulator, verbose); |
8eab189b MM |
230 | } |
231 | ||
232 | ||
233 | void | |
234 | sim_create_inferior (SIM_ADDR start_address, char **argv, char **envp) | |
235 | { | |
236 | unsigned_word entry_point = start_address; | |
237 | ||
238 | TRACE(trace_gdb, ("sim_create_inferior(start_address=0x%x, ...)\n", | |
239 | start_address)); | |
240 | ||
a983c8f0 | 241 | psim_init(simulator); |
8eab189b MM |
242 | psim_stack(simulator, argv, envp); |
243 | ||
244 | psim_write_register(simulator, -1 /* all start at same PC */, | |
245 | &entry_point, "pc", cooked_transfer); | |
246 | } | |
247 | ||
248 | ||
249 | static volatile int sim_should_run; | |
250 | ||
251 | void | |
252 | sim_stop_reason (enum sim_stop *reason, int *sigrc) | |
253 | { | |
254 | psim_status status = psim_get_status(simulator); | |
255 | ||
256 | switch (CURRENT_ENVIRONMENT) { | |
257 | ||
a983c8f0 | 258 | case USER_ENVIRONMENT: |
8eab189b MM |
259 | case VIRTUAL_ENVIRONMENT: |
260 | switch (status.reason) { | |
261 | case was_continuing: | |
262 | *reason = sim_stopped; | |
263 | *sigrc = SIGTRAP; | |
264 | if (sim_should_run) { | |
265 | error("sim_stop_reason() unknown reason for halt\n"); | |
266 | } | |
267 | break; | |
268 | case was_trap: | |
269 | *reason = sim_stopped; | |
270 | *sigrc = SIGTRAP; | |
271 | break; | |
272 | case was_exited: | |
273 | *reason = sim_exited; | |
274 | *sigrc = 0; | |
275 | break; | |
276 | case was_signalled: | |
277 | *reason = sim_signalled; | |
278 | *sigrc = status.signal; | |
279 | break; | |
280 | } | |
281 | break; | |
282 | ||
283 | case OPERATING_ENVIRONMENT: | |
284 | *reason = sim_stopped; | |
285 | *sigrc = SIGTRAP; | |
286 | break; | |
287 | ||
288 | default: | |
289 | error("sim_stop_reason() - unknown environment\n"); | |
290 | ||
291 | } | |
a983c8f0 | 292 | |
28816f45 MM |
293 | TRACE(trace_gdb, ("sim_stop_reason(reason=0x%lx(%ld), sigrc=0x%lx(%ld))\n", |
294 | (long)reason, (long)*reason, (long)sigrc, (long)*sigrc)); | |
8eab189b MM |
295 | } |
296 | ||
297 | ||
298 | ||
299 | /* Run (or resume) the program. */ | |
300 | static void | |
301 | sim_ctrl_c() | |
302 | { | |
303 | sim_should_run = 0; | |
304 | } | |
305 | ||
306 | void | |
307 | sim_resume (int step, int siggnal) | |
308 | { | |
309 | void (*prev) (); | |
8eab189b | 310 | |
a983c8f0 MM |
311 | TRACE(trace_gdb, ("sim_resume(step=%d, siggnal=%d)\n", |
312 | step, siggnal)); | |
313 | ||
8eab189b MM |
314 | prev = signal(SIGINT, sim_ctrl_c); |
315 | sim_should_run = 1; | |
316 | ||
317 | if (step) | |
318 | psim_step(simulator); | |
319 | else | |
320 | psim_run_until_stop(simulator, &sim_should_run); | |
321 | ||
322 | signal(SIGINT, prev); | |
323 | } | |
324 | ||
325 | void | |
326 | sim_do_command(char *cmd) | |
327 | { | |
328 | TRACE(trace_gdb, ("sim_do_commands(cmd=%s) called\n", cmd)); | |
329 | } | |
330 | ||
f46f3807 MM |
331 | void |
332 | sim_set_callbacks (host_callback *callback) | |
333 | { | |
334 | TRACE(trace_gdb, ("sim_set_callbacks called\n")); | |
335 | } | |
336 | ||
8eab189b MM |
337 | /****/ |
338 | ||
339 | void * | |
340 | zalloc(long size) | |
341 | { | |
342 | void *memory = (void*)xmalloc(size); | |
343 | if (memory == NULL) | |
344 | error("xmalloc failed\n"); | |
290ad14a | 345 | memset(memory, 0, size); |
8eab189b MM |
346 | return memory; |
347 | } | |
348 | ||
349 | void zfree(void *data) | |
350 | { | |
351 | mfree(NULL, data); | |
352 | } |