]>
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 | ||
26 | #include "basics.h" | |
27 | #include "psim.h" | |
28 | ||
c494cadd MM |
29 | #ifdef HAVE_STDLIB_H |
30 | #include <stdlib.h> | |
31 | #endif | |
32 | ||
33 | #ifdef HAVE_STRING_H | |
34 | #include <string.h> | |
35 | #else | |
36 | #ifdef HAVE_STRINGS_H | |
37 | #include <strings.h> | |
38 | #endif | |
39 | #endif | |
40 | ||
8eab189b MM |
41 | #include "../../gdb/defs.h" |
42 | ||
43 | #include "devices.h" | |
44 | ||
45 | #include "../../gdb/remote-sim.h" | |
f46f3807 | 46 | #include "../../gdb/callback.h" |
8eab189b MM |
47 | |
48 | ||
49 | /* Structures used by the simulator, for gdb just have static structures */ | |
50 | ||
51 | static psim *simulator; | |
8eab189b | 52 | static char *register_names[] = REGISTER_NAMES; |
83d96c6e | 53 | static int print_info = 0; |
8eab189b MM |
54 | |
55 | void | |
56 | sim_open (char *args) | |
57 | { | |
58 | int i; | |
59 | ||
60 | /* trace the call */ | |
61 | TRACE(trace_gdb, ("sim_open(args=%s) called\n", args ? args : "(null)")); | |
62 | ||
63 | if (args) { | |
a983c8f0 MM |
64 | char **argv = buildargv(args); |
65 | int argp = 0; | |
66 | int argc; | |
67 | for (argc = 0; argv[argc]; argc++); | |
8eab189b | 68 | |
a983c8f0 MM |
69 | while (argp < argc) { |
70 | if (*argv[argp] != '-') | |
71 | error ("Argument is not an option '%s'", argv[argp]); | |
8eab189b MM |
72 | |
73 | else { | |
74 | /* check arguments -- note, main.c also contains argument processing | |
75 | code for the standalone emulator. */ | |
a983c8f0 MM |
76 | char *p = argv[argp] + 1; |
77 | while (*p != '\0') { | |
8eab189b MM |
78 | switch (*p) { |
79 | default: | |
a983c8f0 MM |
80 | printf_filtered("Usage:\n\ttarget sim [ -t <trace-option> ]\n"); |
81 | trace_usage(); | |
82 | error (""); | |
8eab189b | 83 | break; |
a983c8f0 MM |
84 | case 't': |
85 | argp += 1; | |
86 | if (argv[argp] == NULL) | |
87 | error("Missing <trace> option for -t\n"); | |
88 | trace_option(argv[argp]); /* better fail if NULL */ | |
8eab189b | 89 | break; |
83d96c6e MM |
90 | case 'I': |
91 | print_info = 1; | |
92 | break; | |
8eab189b MM |
93 | } |
94 | } | |
95 | } | |
a983c8f0 | 96 | argp += 1; |
8eab189b MM |
97 | } |
98 | } | |
99 | ||
100 | /* do something */ | |
101 | TRACE(trace_tbd, ("sim_open() - TBD - should parse the arguments\n")); | |
102 | TRACE(trace_tbd, ("sim_open() - TBD - can not create simulator here as do not have description of it\n")); | |
103 | } | |
104 | ||
105 | ||
106 | void | |
107 | sim_close (int quitting) | |
108 | { | |
109 | TRACE(trace_gdb, ("sim_close(quitting=%d) called\n", quitting)); | |
83d96c6e MM |
110 | if (print_info) |
111 | psim_print_info (simulator, 1); | |
112 | ||
8eab189b MM |
113 | /* nothing to do */ |
114 | } | |
115 | ||
116 | ||
117 | int | |
118 | sim_load (char *prog, int from_tty) | |
119 | { | |
a983c8f0 | 120 | char **argv; |
8eab189b MM |
121 | TRACE(trace_gdb, ("sim_load(prog=%s, from_tty=%d) called\n", |
122 | prog, from_tty)); | |
a983c8f0 | 123 | ASSERT(prog != NULL); |
8eab189b | 124 | |
a983c8f0 MM |
125 | /* parse the arguments, assume that the file is argument 0 */ |
126 | argv = buildargv(prog); | |
127 | ASSERT(argv != NULL && argv[0] != NULL); | |
8eab189b MM |
128 | |
129 | /* create the simulator */ | |
130 | TRACE(trace_gdb, ("sim_load() - first time, create the simulator\n")); | |
a983c8f0 | 131 | simulator = psim_create(argv[0]); |
8eab189b MM |
132 | |
133 | /* bring in all the data section */ | |
a983c8f0 | 134 | psim_init(simulator); |
8eab189b | 135 | |
a983c8f0 MM |
136 | /* release the arguments */ |
137 | freeargv(argv); | |
138 | ||
139 | /* `I did it my way' */ | |
8eab189b MM |
140 | return 0; |
141 | } | |
142 | ||
143 | ||
144 | void | |
145 | sim_kill (void) | |
146 | { | |
147 | TRACE(trace_gdb, ("sim_kill(void) called\n")); | |
148 | /* do nothing, nothing to do */ | |
149 | } | |
150 | ||
151 | ||
152 | int | |
153 | sim_read (SIM_ADDR mem, unsigned char *buf, int length) | |
154 | { | |
a983c8f0 MM |
155 | int result = psim_read_memory(simulator, MAX_NR_PROCESSORS, |
156 | buf, mem, length); | |
157 | TRACE(trace_gdb, ("sim_read(mem=0x%x, buf=0x%x, length=%d) = %d\n", | |
158 | mem, buf, length, result)); | |
159 | return result; | |
8eab189b MM |
160 | } |
161 | ||
162 | ||
163 | int | |
164 | sim_write (SIM_ADDR mem, unsigned char *buf, int length) | |
165 | { | |
a983c8f0 MM |
166 | int result = psim_write_memory(simulator, MAX_NR_PROCESSORS, |
167 | buf, mem, length, | |
168 | 1/*violate_ro*/); | |
169 | TRACE(trace_gdb, ("sim_write(mem=0x%x, buf=0x%x, length=%d) = %d\n", | |
170 | mem, buf, length, result)); | |
171 | return result; | |
8eab189b MM |
172 | } |
173 | ||
174 | ||
175 | void | |
176 | sim_fetch_register (int regno, unsigned char *buf) | |
177 | { | |
178 | if (simulator == NULL) { | |
179 | return; | |
180 | } | |
a983c8f0 MM |
181 | TRACE(trace_gdb, ("sim_fetch_register(regno=%d(%s), buf=0x%x)\n", |
182 | regno, register_names[regno], buf)); | |
183 | psim_read_register(simulator, MAX_NR_PROCESSORS, | |
184 | buf, register_names[regno], | |
8eab189b MM |
185 | raw_transfer); |
186 | } | |
187 | ||
188 | ||
189 | void | |
190 | sim_store_register (int regno, unsigned char *buf) | |
191 | { | |
192 | if (simulator == NULL) | |
193 | return; | |
a983c8f0 MM |
194 | TRACE(trace_gdb, ("sim_store_register(regno=%d(%s), buf=0x%x)\n", |
195 | regno, register_names[regno], buf)); | |
196 | psim_write_register(simulator, MAX_NR_PROCESSORS, | |
197 | buf, register_names[regno], | |
8eab189b MM |
198 | raw_transfer); |
199 | } | |
200 | ||
201 | ||
202 | void | |
203 | sim_info (int verbose) | |
204 | { | |
205 | TRACE(trace_gdb, ("sim_info(verbose=%d) called\n", verbose)); | |
83d96c6e | 206 | psim_print_info (simulator, verbose); |
8eab189b MM |
207 | } |
208 | ||
209 | ||
210 | void | |
211 | sim_create_inferior (SIM_ADDR start_address, char **argv, char **envp) | |
212 | { | |
213 | unsigned_word entry_point = start_address; | |
214 | ||
215 | TRACE(trace_gdb, ("sim_create_inferior(start_address=0x%x, ...)\n", | |
216 | start_address)); | |
217 | ||
a983c8f0 | 218 | psim_init(simulator); |
8eab189b MM |
219 | psim_stack(simulator, argv, envp); |
220 | ||
221 | psim_write_register(simulator, -1 /* all start at same PC */, | |
222 | &entry_point, "pc", cooked_transfer); | |
223 | } | |
224 | ||
225 | ||
226 | static volatile int sim_should_run; | |
227 | ||
228 | void | |
229 | sim_stop_reason (enum sim_stop *reason, int *sigrc) | |
230 | { | |
231 | psim_status status = psim_get_status(simulator); | |
232 | ||
233 | switch (CURRENT_ENVIRONMENT) { | |
234 | ||
a983c8f0 | 235 | case USER_ENVIRONMENT: |
8eab189b MM |
236 | case VIRTUAL_ENVIRONMENT: |
237 | switch (status.reason) { | |
238 | case was_continuing: | |
239 | *reason = sim_stopped; | |
240 | *sigrc = SIGTRAP; | |
241 | if (sim_should_run) { | |
242 | error("sim_stop_reason() unknown reason for halt\n"); | |
243 | } | |
244 | break; | |
245 | case was_trap: | |
246 | *reason = sim_stopped; | |
247 | *sigrc = SIGTRAP; | |
248 | break; | |
249 | case was_exited: | |
250 | *reason = sim_exited; | |
251 | *sigrc = 0; | |
252 | break; | |
253 | case was_signalled: | |
254 | *reason = sim_signalled; | |
255 | *sigrc = status.signal; | |
256 | break; | |
257 | } | |
258 | break; | |
259 | ||
260 | case OPERATING_ENVIRONMENT: | |
261 | *reason = sim_stopped; | |
262 | *sigrc = SIGTRAP; | |
263 | break; | |
264 | ||
265 | default: | |
266 | error("sim_stop_reason() - unknown environment\n"); | |
267 | ||
268 | } | |
a983c8f0 MM |
269 | |
270 | TRACE(trace_gdb, ("sim_stop_reason(reason=0x%x(%d), sigrc=0x%x(%d))\n", | |
271 | reason, *reason, sigrc, *sigrc)); | |
8eab189b MM |
272 | } |
273 | ||
274 | ||
275 | ||
276 | /* Run (or resume) the program. */ | |
277 | static void | |
278 | sim_ctrl_c() | |
279 | { | |
280 | sim_should_run = 0; | |
281 | } | |
282 | ||
283 | void | |
284 | sim_resume (int step, int siggnal) | |
285 | { | |
286 | void (*prev) (); | |
287 | unsigned_word program_counter; | |
288 | ||
a983c8f0 MM |
289 | TRACE(trace_gdb, ("sim_resume(step=%d, siggnal=%d)\n", |
290 | step, siggnal)); | |
291 | ||
8eab189b MM |
292 | prev = signal(SIGINT, sim_ctrl_c); |
293 | sim_should_run = 1; | |
294 | ||
295 | if (step) | |
296 | psim_step(simulator); | |
297 | else | |
298 | psim_run_until_stop(simulator, &sim_should_run); | |
299 | ||
300 | signal(SIGINT, prev); | |
301 | } | |
302 | ||
303 | void | |
304 | sim_do_command(char *cmd) | |
305 | { | |
306 | TRACE(trace_gdb, ("sim_do_commands(cmd=%s) called\n", cmd)); | |
307 | } | |
308 | ||
f46f3807 MM |
309 | void |
310 | sim_set_callbacks (host_callback *callback) | |
311 | { | |
312 | TRACE(trace_gdb, ("sim_set_callbacks called\n")); | |
313 | } | |
314 | ||
8eab189b MM |
315 | /****/ |
316 | ||
317 | void * | |
318 | zalloc(long size) | |
319 | { | |
320 | void *memory = (void*)xmalloc(size); | |
321 | if (memory == NULL) | |
322 | error("xmalloc failed\n"); | |
323 | bzero(memory, size); | |
324 | return memory; | |
325 | } | |
326 | ||
327 | void zfree(void *data) | |
328 | { | |
329 | mfree(NULL, data); | |
330 | } |