]>
Commit | Line | Data |
---|---|---|
a332e593 | 1 | /* Remote debugging interface for Zilog Z8000 simulator |
f48c6d1a | 2 | Copyright 1992,1993 Free Software Foundation, Inc. |
a332e593 SC |
3 | Contributed by Cygnus Support. Written by Steve Chamberlain |
4 | ([email protected]). | |
5 | ||
6 | This file is part of GDB. | |
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 2 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, write to the Free Software | |
20 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
21 | ||
22 | #include "defs.h" | |
23 | #include "inferior.h" | |
24 | #include "wait.h" | |
25 | #include "value.h" | |
26 | #include <string.h> | |
27 | #include <ctype.h> | |
28 | #include <fcntl.h> | |
29 | #include <signal.h> | |
30 | #include <setjmp.h> | |
31 | #include <errno.h> | |
32 | #include "terminal.h" | |
33 | #include "target.h" | |
34 | #include "gdbcore.h" | |
6d2f03fe | 35 | #include "../sim/z8k/sim.h" |
a332e593 SC |
36 | |
37 | /* External data declarations */ | |
e4ebb8e5 | 38 | extern int stop_soon_quietly; /* for wait_for_inferior */ |
a332e593 SC |
39 | |
40 | /* Forward data declarations */ | |
e4ebb8e5 | 41 | extern struct target_ops sim_ops; /* Forward declaration */ |
a332e593 | 42 | |
e4ebb8e5 SC |
43 | void sim_store_register (); |
44 | void sim_set_oc (); | |
a332e593 SC |
45 | |
46 | int | |
47 | sim_write_inferior_memory (memaddr, myaddr, len) | |
48 | CORE_ADDR memaddr; | |
49 | unsigned char *myaddr; | |
50 | int len; | |
51 | { | |
e4ebb8e5 | 52 | sim_write (memaddr, myaddr, len); |
1f21d3dc | 53 | return 1; |
a332e593 SC |
54 | } |
55 | ||
1f21d3dc | 56 | static void |
e4ebb8e5 SC |
57 | store_register (regno) |
58 | int regno; | |
a332e593 | 59 | { |
e4ebb8e5 SC |
60 | if (regno == -1) |
61 | { | |
62 | for (regno = 0; regno < 16; regno++) | |
63 | { | |
64 | store_register (regno); | |
65 | } | |
66 | } | |
67 | else | |
f48c6d1a | 68 | { |
e4ebb8e5 | 69 | sim_store_register (regno, read_register (regno)); |
f48c6d1a | 70 | } |
a332e593 SC |
71 | } |
72 | ||
a332e593 | 73 | void |
e4ebb8e5 SC |
74 | sim_kill (arg, from_tty) |
75 | char *arg; | |
76 | int from_tty; | |
a332e593 SC |
77 | { |
78 | ||
79 | } | |
80 | ||
a332e593 | 81 | /* |
e4ebb8e5 | 82 | * Download a file specified in 'args', to the sim. |
a332e593 SC |
83 | */ |
84 | static void | |
e4ebb8e5 SC |
85 | sim_load (args, fromtty) |
86 | char *args; | |
87 | int fromtty; | |
a332e593 | 88 | { |
e4ebb8e5 | 89 | bfd *abfd; |
a332e593 SC |
90 | asection *s; |
91 | ||
e4ebb8e5 SC |
92 | inferior_pid = 0; |
93 | abfd = bfd_openr (args, "coff-z8k"); | |
a332e593 | 94 | |
e4ebb8e5 SC |
95 | if (!abfd) |
96 | { | |
97 | printf_filtered ("Unable to open file %s\n", args); | |
98 | return; | |
99 | } | |
a332e593 | 100 | |
e4ebb8e5 SC |
101 | if (bfd_check_format (abfd, bfd_object) == 0) |
102 | { | |
103 | printf_filtered ("File is not an object file\n"); | |
104 | return; | |
105 | } | |
a332e593 SC |
106 | |
107 | s = abfd->sections; | |
e4ebb8e5 | 108 | while (s != (asection *) NULL) |
a332e593 | 109 | { |
e4ebb8e5 SC |
110 | if (s->flags & SEC_LOAD) |
111 | { | |
112 | int i; | |
113 | int delta = 4096; | |
114 | char *buffer = xmalloc (delta); | |
115 | ||
116 | printf_filtered ("%s\t: 0x%4x .. 0x%4x ", | |
117 | s->name, s->vma, s->vma + s->_raw_size); | |
118 | for (i = 0; i < s->_raw_size; i += delta) | |
119 | { | |
120 | int sub_delta = delta; | |
121 | ||
122 | if (sub_delta > s->_raw_size - i) | |
123 | sub_delta = s->_raw_size - i; | |
124 | ||
125 | bfd_get_section_contents (abfd, s, buffer, i, sub_delta); | |
126 | sim_write_inferior_memory (s->vma + i, buffer, sub_delta); | |
127 | printf_filtered ("*"); | |
128 | fflush (stdout); | |
129 | } | |
130 | printf_filtered ("\n"); | |
131 | free (buffer); | |
132 | } | |
133 | s = s->next; | |
a332e593 | 134 | } |
a332e593 | 135 | |
e4ebb8e5 | 136 | sim_set_pc (abfd->start_address); |
a332e593 SC |
137 | } |
138 | ||
139 | /* This is called not only when we first attach, but also when the | |
140 | user types "run" after having attached. */ | |
1f21d3dc | 141 | static void |
a332e593 SC |
142 | sim_create_inferior (execfile, args, env) |
143 | char *execfile; | |
144 | char *args; | |
145 | char **env; | |
146 | { | |
147 | int entry_pt; | |
a332e593 SC |
148 | |
149 | if (args && *args) | |
e4ebb8e5 | 150 | error ("Can't pass arguments to remote sim process."); |
a332e593 SC |
151 | |
152 | if (execfile == 0 || exec_bfd == 0) | |
e4ebb8e5 | 153 | error ("No exec file specified"); |
a332e593 SC |
154 | |
155 | entry_pt = (int) bfd_get_start_address (exec_bfd); | |
156 | ||
e4ebb8e5 SC |
157 | sim_kill (NULL, NULL); |
158 | sim_clear_breakpoints (); | |
a332e593 | 159 | init_wait_for_inferior (); |
1f21d3dc | 160 | insert_breakpoints (); |
e4ebb8e5 | 161 | proceed (entry_pt, -1, 0); |
a332e593 SC |
162 | } |
163 | ||
a332e593 SC |
164 | static void |
165 | sim_open (name, from_tty) | |
166 | char *name; | |
167 | int from_tty; | |
168 | { | |
e4ebb8e5 SC |
169 | if (name == 0) |
170 | { | |
171 | name = ""; | |
172 | } | |
a332e593 SC |
173 | |
174 | /* Clear any break points */ | |
e4ebb8e5 | 175 | sim_clear_breakpoints (); |
a332e593 SC |
176 | |
177 | push_target (&sim_ops); | |
e4ebb8e5 | 178 | target_fetch_registers (-1); |
a332e593 | 179 | |
e4ebb8e5 | 180 | printf_filtered ("Connected to the Z8000 Simulator.\n"); |
a332e593 SC |
181 | } |
182 | ||
183 | /* Close out all files and local state before this target loses control. */ | |
184 | ||
185 | static void | |
186 | sim_close (quitting) | |
187 | int quitting; | |
188 | { | |
e4ebb8e5 | 189 | sim_clear_breakpoints (); |
a332e593 SC |
190 | } |
191 | ||
192 | /* Terminate the open connection to the remote debugger. | |
193 | Use this when you want to detach and do something else | |
194 | with your gdb. */ | |
1f21d3dc | 195 | static void |
e4ebb8e5 | 196 | sim_detach (args, from_tty) |
a332e593 SC |
197 | char *args; |
198 | int from_tty; | |
199 | { | |
e4ebb8e5 SC |
200 | sim_clear_breakpoints (); |
201 | ||
202 | pop_target (); /* calls sim_close to do the real work */ | |
a332e593 | 203 | if (from_tty) |
e4ebb8e5 | 204 | printf_filtered ("Ending remote %s debugging\n", target_shortname); |
a332e593 | 205 | } |
a332e593 | 206 | |
e4ebb8e5 | 207 | /* Tell the remote machine to resume. */ |
a332e593 SC |
208 | |
209 | /* Wait until the remote machine stops, then return, | |
210 | storing status in STATUS just as `wait' would. */ | |
211 | ||
212 | int | |
213 | sim_wait (status) | |
214 | WAITTYPE *status; | |
215 | { | |
e4ebb8e5 | 216 | *status = sim_stop_signal (); |
1f21d3dc | 217 | return 0; |
a332e593 SC |
218 | } |
219 | ||
a332e593 SC |
220 | /* Get ready to modify the registers array. On machines which store |
221 | individual registers, this doesn't need to do anything. On machines | |
222 | which store all the registers in one fell swoop, this makes sure | |
223 | that registers contains all the registers from the program being | |
224 | debugged. */ | |
225 | ||
1f21d3dc | 226 | static void |
a332e593 SC |
227 | sim_prepare_to_store () |
228 | { | |
229 | /* Do nothing, since we can store individual regs */ | |
230 | } | |
231 | ||
a332e593 | 232 | static void |
e4ebb8e5 SC |
233 | fetch_register (regno) |
234 | int regno; | |
a332e593 | 235 | { |
e4ebb8e5 SC |
236 | if (regno == -1) |
237 | { | |
238 | for (regno = 0; regno < 16; regno++) | |
239 | fetch_register (regno); | |
240 | } | |
241 | else | |
242 | { | |
243 | char buf[MAX_REGISTER_RAW_SIZE]; | |
244 | ||
245 | sim_fetch_register (regno, buf); | |
246 | supply_register (regno, buf); | |
247 | } | |
a332e593 SC |
248 | } |
249 | ||
250 | /* Write a word WORD into remote address ADDR. | |
251 | This goes through the data cache. */ | |
252 | ||
253 | void | |
254 | sim_store_word (addr, word) | |
255 | CORE_ADDR addr; | |
256 | int word; | |
257 | { | |
258 | /* dcache_poke (addr, word);*/ | |
259 | } | |
260 | ||
261 | int | |
e4ebb8e5 | 262 | sim_xfer_inferior_memory (memaddr, myaddr, len, write, target) |
a332e593 SC |
263 | CORE_ADDR memaddr; |
264 | char *myaddr; | |
265 | int len; | |
266 | int write; | |
e4ebb8e5 | 267 | struct target_ops *target; /* ignored */ |
a332e593 SC |
268 | { |
269 | if (write) | |
e4ebb8e5 SC |
270 | { |
271 | sim_write (memaddr, myaddr, len); | |
272 | ||
273 | } | |
274 | else | |
275 | { | |
276 | sim_read (memaddr, myaddr, len); | |
277 | } | |
278 | return len; | |
a332e593 SC |
279 | } |
280 | ||
281 | void | |
282 | sim_files_info () | |
283 | { | |
f48c6d1a | 284 | char *file = "nothing"; |
e4ebb8e5 | 285 | |
f48c6d1a | 286 | if (exec_bfd) |
e4ebb8e5 | 287 | file = bfd_get_filename (exec_bfd); |
f48c6d1a | 288 | |
e4ebb8e5 | 289 | printf_filtered ("\tAttached to %s running on the z8k simulator\n", file); |
a332e593 SC |
290 | } |
291 | ||
292 | /* This routine is run as a hook, just before the main command loop is | |
293 | entered. If gdb is configured for the H8, but has not had its | |
294 | target specified yet, this will loop prompting the user to do so. | |
295 | */ | |
296 | ||
297 | void | |
298 | sim_before_main_loop () | |
299 | { | |
a332e593 SC |
300 | push_target (&sim_ops); |
301 | } | |
302 | ||
a332e593 | 303 | /* Clear the sims notion of what the break points are */ |
1f21d3dc | 304 | static void |
e4ebb8e5 SC |
305 | sim_mourn () |
306 | { | |
307 | sim_clear_breakpoints (); | |
71607f9d | 308 | unpush_target (&sim_ops); |
a332e593 | 309 | generic_mourn_inferior (); |
a332e593 SC |
310 | } |
311 | ||
e4ebb8e5 | 312 | static void |
25286543 SG |
313 | rem_resume (pid, a, b) |
314 | int pid; | |
e4ebb8e5 SC |
315 | int a; |
316 | int b; | |
a332e593 | 317 | { |
e4ebb8e5 | 318 | sim_resume (a, b); |
a332e593 SC |
319 | } |
320 | ||
321 | /* Define the target subroutine names */ | |
322 | ||
e4ebb8e5 | 323 | struct target_ops sim_ops = |
a332e593 SC |
324 | { |
325 | "sim", "Remote SIM monitor", | |
326 | "Use the Z8000 simulator", | |
e4ebb8e5 SC |
327 | sim_open, sim_close, |
328 | 0, sim_detach, rem_resume, sim_wait, /* attach */ | |
a332e593 SC |
329 | fetch_register, store_register, |
330 | sim_prepare_to_store, | |
e4ebb8e5 | 331 | sim_xfer_inferior_memory, |
a332e593 | 332 | sim_files_info, |
e4ebb8e5 | 333 | 0, 0, /* Breakpoints */ |
a332e593 SC |
334 | 0, 0, 0, 0, 0, /* Terminal handling */ |
335 | sim_kill, /* FIXME, kill */ | |
e4ebb8e5 | 336 | sim_load, |
a332e593 | 337 | 0, /* lookup_symbol */ |
e4ebb8e5 | 338 | sim_create_inferior, /* create_inferior */ |
a332e593 SC |
339 | sim_mourn, /* mourn_inferior FIXME */ |
340 | 0, /* can_run */ | |
341 | 0, /* notice_signals */ | |
342 | process_stratum, 0, /* next */ | |
343 | 1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */ | |
e4ebb8e5 | 344 | 0, 0, /* Section pointers */ |
a332e593 SC |
345 | OPS_MAGIC, /* Always the last thing */ |
346 | }; | |
347 | ||
a332e593 SC |
348 | /***********************************************************************/ |
349 | ||
350 | void | |
351 | _initialize_remote_sim () | |
352 | { | |
353 | extern int sim_z8001_mode; | |
e4ebb8e5 | 354 | |
a332e593 SC |
355 | sim_z8001_mode = z8001_mode; |
356 | add_target (&sim_ops); | |
a332e593 | 357 | |
e4ebb8e5 | 358 | } |