]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/v850ice.c
This commit was generated by cvs2svn to track changes on a CVS vendor
[thirdparty/binutils-gdb.git] / gdb / v850ice.c
1 /* ICE interface for the NEC V850 for GDB, the GNU debugger.
2 Copyright 1996, Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
19
20 #include "defs.h"
21 #include "gdb_string.h"
22 #if 0
23 #include "frame.h"
24 #endif
25 #include "inferior.h"
26 #if 0
27 #include "bfd.h"
28 #endif
29 #include "symfile.h"
30 #include "target.h"
31 #if 0
32 #include "wait.h"
33 #include "gdbcmd.h"
34 #include "objfiles.h"
35 #include "gdb-stabs.h"
36 #include "gdbthread.h"
37 #endif
38 #define WIN32_LEAN_AND_MEAN
39 #include <windows.h>
40
41 /* Prototypes for local functions */
42
43 static void v850ice_files_info PARAMS ((struct target_ops *ignore));
44
45 static int v850ice_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
46 int len, int should_write,
47 struct target_ops *target));
48
49 static void v850ice_prepare_to_store PARAMS ((void));
50
51 static void v850ice_fetch_registers PARAMS ((int regno));
52
53 static void v850ice_resume PARAMS ((int pid, int step,
54 enum target_signal siggnal));
55
56 static void v850ice_open PARAMS ((char *name, int from_tty));
57
58 static void v850ice_close PARAMS ((int quitting));
59
60 static void v850ice_store_registers PARAMS ((int regno));
61
62 static void v850ice_mourn PARAMS ((void));
63
64 static int v850ice_wait PARAMS ((int pid, struct target_waitstatus *status));
65
66 static void v850ice_kill PARAMS ((void));
67
68 static void v850ice_detach PARAMS ((char *args, int from_tty));
69
70 static int v850ice_insert_breakpoint PARAMS ((CORE_ADDR, char *));
71
72 static int v850ice_remove_breakpoint PARAMS ((CORE_ADDR, char *));
73
74 static int ice_open = 0;
75
76 #ifndef EXPORT
77 #define EXPORT __declspec(dllexport)
78 #endif
79
80 struct MessageIO
81 {
82 int size; /* length of input or output in bytes */
83 char *buf; /* buffer having the input/output information */
84 };
85
86 struct MessageIO null_iob = { 0, NULL };
87
88 EXPORT long __stdcall ExeAppReq (char *, long, char *, struct MessageIO *);
89 EXPORT long __stdcall RegisterClient (HWND);
90 EXPORT long __stdcall UnregisterClient (void);
91 EXPORT long __stdcall GdbCallBack (void);
92
93 #define MREADREG 0x0001
94 #define MWRITEREG 0x0002
95 #define MREADMEM 0x0003
96 #define MWRITEMEM 0x0004
97 #define MSINGLESTEP 0x0005
98 #define MRESUME 0x0006
99 #define MLOADPROGRAM 0x0007
100 #define MSETBREAK 0x0008
101 #define MREMOVEBREAK 0x0009
102 #define MQUIT 0x000A
103 #define MTERMINATE 0x000B
104 #define MATTACH 0x000C
105 #define MCHECKSTATUS 0x000D
106 #define MHALT 0x000E
107 #define MDIRECTCMD 0x000F
108 #define MSYMADR 0x0010
109 #define MGETTASKLIST 0x0011
110 #define MREADVECREG 0x0012
111 #define MWRITEVECREG 0x0013
112 #define MGETCHANGEDREGS 0x0014
113 #define MGETSERVERINFO 0x0015
114 #define MREADBLOCK 0x0016
115 #define MSETHARDBRK 0x0017
116 #define MREMOVEHARDBRK 0x0018
117 #define MCOPYBLOCK 0x0019
118 #define MBLOCKFILL 0x001A
119 #define MFINDBLOCK 0x001B
120 #define MCOMPAREBLOCK 0x001C
121 #define MREFRESH 0x001D
122 #define MSPECIAL 0x001E
123 #define MGETCMDLIST 0x001F
124 #define MEXPVAL 0x0020
125 #define MEXPFAILED 0x0021
126 #define MSAVESTATE 0x0022
127 #define MWRITEBLOCK 0x0023
128 #define MDETACH 0x0024
129 #define MGETMODULES 0x0025
130 #define MREMOTESYMBOL 0x0026
131 #define MREADCSTRING 0x0027
132 #define MLOADMODULE 0x0028
133 #define MDIDSYSCALL 0x0029
134 #define MDBPWRITEBUFFERS 0x002A
135 #define MBPID 0x002B
136 #define MINITEXEC 0x002C
137 #define MEXITEXEC 0x002D
138 #define MRCCMD 0x002E
139 #define MDOWNLOAD 0x0050
140
141 #define StatRunning 0
142 #define StatExecBreak 1 /* an execution breakpoint has been reached */
143 #define StatStepped 2 /* a single step has been completed */
144 #define StatException 3 /* the target has stopped due to an exception */
145 #define StatHalted 4 /* target has been halted by a user request */
146 #define StatExited 5 /* target called exit */
147 #define StatTerminated 6 /* target program terminated by a user request */
148 #define StatNoProcess 7 /* no process on target and none of the above */
149 #define StatNeedInput 8 /* REV: obsolete */
150 #define StatNeedDirCmd 9 /* waiting for an entry in the remote window */
151 #define StatHardBreak 10 /* hit hardware breakpoint */
152 #define StatFailure 11 /* an error occured in the last run/single */
153
154 extern struct target_ops v850ice_ops; /* Forward decl */
155
156 /* "pir", "tkcw", "chcw", "adtre" */
157
158 /* Code for opening a connection to the ICE. */
159
160 static void
161 v850ice_open (name, from_tty)
162 char *name;
163 int from_tty;
164 {
165 long retval;
166
167 if (name)
168 error ("Too many arguments.");
169
170 target_preopen (from_tty);
171
172 unpush_target (&v850ice_ops);
173
174 if (from_tty)
175 puts_filtered ("V850ice debugging\n");
176
177 push_target (&v850ice_ops); /* Switch to using v850ice target now */
178
179 target_terminal_init ();
180
181 /* Without this, some commands which require an active target (such as kill)
182 won't work. This variable serves (at least) double duty as both the pid
183 of the target process (if it has such), and as a flag indicating that a
184 target is active. These functions should be split out into seperate
185 variables, especially since GDB will someday have a notion of debugging
186 several processes. */
187
188 inferior_pid = 42000;
189
190 /* Start the v850ice connection; if error (0), discard this target.
191 In particular, if the user quits, be sure to discard it
192 (we'd be in an inconsistent state otherwise). */
193
194 WinExec ("necsrv", SW_SHOW); /* Start up necsrv */
195
196 retval = RegisterClient (NULL);
197
198 if (retval == 0)
199 {
200 ice_open = 1;
201
202 start_remote ();
203 return;
204 }
205
206 pop_target();
207
208 error ("v850ice_open: MINITEXEC return error: 0x%x", retval);
209 }
210
211 /* Clean up connection to a remote debugger. */
212
213 /* ARGSUSED */
214 static void
215 v850ice_close (quitting)
216 int quitting;
217 {
218 long retval;
219
220 if (ice_open)
221 {
222 #if 0
223 retval = ExeAppReq ("GDB", MEXITEXEC, NULL, &null_iob);
224 if (retval)
225 error ("ExeAppReq (MEXITEXEC) returned %d", retval);
226 #endif
227 ice_open = 0;
228 UnregisterClient ();
229 }
230 }
231
232 static void
233 v850ice_detach (args, from_tty)
234 char *args;
235 int from_tty;
236 {
237 if (args)
238 error ("Argument given to \"detach\" when remotely debugging.");
239
240 pop_target ();
241 if (from_tty)
242 puts_filtered ("Ending v850ice debugging.\n");
243 }
244
245 /* Tell the remote machine to resume. */
246
247 static void
248 v850ice_resume (pid, step, siggnal)
249 int pid, step;
250 enum target_signal siggnal;
251 {
252 long retval;
253
254 if (step)
255 retval = ExeAppReq ("GDB", MSINGLESTEP, "step", &null_iob);
256 else
257 retval = ExeAppReq ("GDB", MRESUME, "run", &null_iob);
258
259 if (retval)
260 error ("ExeAppReq (step = %d) returned %d", step, retval);
261 }
262
263 /* Wait until the remote machine stops, then return,
264 storing status in STATUS just as `wait' would.
265 Returns "pid" (though it's not clear what, if anything, that
266 means in the case of this target). */
267
268 static int
269 v850ice_wait (pid, status)
270 int pid;
271 struct target_waitstatus *status;
272 {
273 long v850_status;
274
275 v850_status = ExeAppReq ("GDB", MCHECKSTATUS, NULL, &null_iob);
276
277 status->kind = TARGET_WAITKIND_STOPPED;
278 status->value.sig = TARGET_SIGNAL_TRAP;
279
280 return inferior_pid;
281 }
282
283 static int
284 convert_register (regno, buf)
285 int regno;
286 char *buf;
287 {
288 if (regno <= 31)
289 sprintf (buf, "r%d", regno);
290 else if (reg_names[regno][0] == 's'
291 && reg_names[regno][1] == 'r')
292 return 0;
293 else
294 sprintf (buf, "%s", reg_names[regno]);
295
296 return 1;
297 }
298
299 /* Read the remote registers into the block REGS. */
300 /* Note that the ICE returns register contents as ascii hex strings. We have
301 to convert that to an unsigned long, and then call store_unsigned_integer to
302 convert it to target byte-order if necessary. */
303
304 static void
305 v850ice_fetch_registers (regno)
306 int regno;
307 {
308 long retval;
309 char cmd[100];
310 char val[100];
311 struct MessageIO iob;
312 unsigned long regval;
313 char *p;
314
315 if (regno == -1)
316 {
317 for (regno = 0; regno < NUM_REGS; regno++)
318 v850ice_fetch_registers (regno);
319 return;
320 }
321
322 strcpy (cmd, "reg ");
323 if (!convert_register (regno, &cmd[4]))
324 return;
325
326 iob.size = sizeof val;
327 iob.buf = val;
328 retval = ExeAppReq ("GDB", MREADREG, cmd, &iob);
329 if (retval)
330 error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
331
332 regval = strtoul (val, &p, 16);
333 if (regval == 0 && p == val)
334 error ("v850ice_fetch_registers (%d): bad value from ICE: %s.",
335 regno, val);
336
337 store_unsigned_integer (val, REGISTER_RAW_SIZE (regno), regval);
338 supply_register (regno, val);
339 }
340
341 /* Store register REGNO, or all registers if REGNO == -1, from the contents
342 of REGISTERS. */
343
344 static void
345 v850ice_store_registers (regno)
346 int regno;
347 {
348 long retval;
349 char cmd[100];
350 unsigned long regval;
351
352 if (regno == -1)
353 {
354 for (regno = 0; regno < NUM_REGS; regno++)
355 v850ice_store_registers (regno);
356 return;
357 }
358
359 regval = extract_unsigned_integer (&registers[REGISTER_BYTE (regno)],
360 REGISTER_RAW_SIZE (regno));
361 strcpy (cmd, "reg ");
362 if (!convert_register (regno, &cmd[4]))
363 return;
364 sprintf (cmd + strlen (cmd), "=0x%x", regval);
365
366 retval = ExeAppReq ("GDB", MWRITEREG, cmd, &null_iob);
367 if (retval)
368 error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
369 }
370
371 /* Prepare to store registers. Nothing to do here, since the ICE can write one
372 register at a time. */
373
374 static void
375 v850ice_prepare_to_store ()
376 {
377 }
378
379 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
380 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
381 nonzero. Returns length of data written or read; 0 for error. */
382
383 /* ARGSUSED */
384 static int
385 v850ice_xfer_memory (memaddr, myaddr, len, should_write, target)
386 CORE_ADDR memaddr;
387 char *myaddr;
388 int len;
389 int should_write;
390 struct target_ops *target; /* ignored */
391 {
392 long retval;
393 char cmd[100];
394 struct MessageIO iob;
395
396 iob.size = len;
397 iob.buf = myaddr;
398
399 if (should_write)
400 {
401 #if 1
402 sprintf (cmd, "memory b c 0x%x=0x00 l=%d", (int)memaddr, len);
403 retval = ExeAppReq ("GDB", MWRITEBLOCK, cmd, &iob);
404 #else
405 sprintf (cmd, "memory b c 0x%x=0x%x", (int)memaddr, *myaddr & 0xff);
406 retval = ExeAppReq ("GDB", MWRITEBLOCK, cmd, &iob);
407 return 1;
408 #endif
409 }
410 else
411 {
412 unsigned char *tmp;
413 int i;
414
415 tmp = alloca (len + 100);
416 memset (tmp + len, 0xff, 100);
417
418 #if 1
419 sprintf (cmd, "memory b 0x%x l=%d", (int)memaddr, len);
420 retval = ExeAppReq ("GDB", MREADBLOCK, cmd, &iob);
421 #else
422 sprintf (cmd, "memory h 0x%x", (int)memaddr);
423 retval = ExeAppReq ("GDB", MREADMEM, cmd, &iob);
424 #endif
425 for (i = 0; i < 100; i++)
426 {
427 if (tmp[len + i] != 0xff)
428 {
429 warning ("MREADBLOCK trashed bytes after transfer area.");
430 break;
431 }
432 }
433 memcpy (myaddr, tmp, len);
434 }
435
436 if (retval)
437 error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
438
439 return len;
440 }
441
442 static void
443 v850ice_files_info (ignore)
444 struct target_ops *ignore;
445 {
446 puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
447 }
448
449 static int
450 v850ice_insert_breakpoint (addr, contents_cache)
451 CORE_ADDR addr;
452 char *contents_cache;
453 {
454 long retval;
455 char cmd[100];
456
457 sprintf (cmd, "%d, ", addr);
458
459 #if 1
460 retval = ExeAppReq ("GDB", MSETBREAK, cmd, &null_iob);
461 #else
462 retval = ExeAppReq ("GDB", MSETHARDBRK, cmd, &null_iob);
463 #endif
464 if (retval)
465 error ("ExeAppReq (MSETBREAK) returned %d: cmd = %s", retval, cmd);
466
467 return 0;
468 }
469
470 static int
471 v850ice_remove_breakpoint (addr, contents_cache)
472 CORE_ADDR addr;
473 char *contents_cache;
474 {
475 long retval;
476 char cmd[100];
477
478 sprintf (cmd, "%d, ", addr);
479
480 #if 1
481 retval = ExeAppReq ("GDB", MREMOVEBREAK, cmd, &null_iob);
482 #else
483 retval = ExeAppReq ("GDB", MREMOVEHARDBRK, cmd, &null_iob);
484 #endif
485 if (retval)
486 error ("ExeAppReq (MREMOVEBREAK) returned %d: cmd = %s", retval, cmd);
487
488 return 0;
489 }
490
491 static void
492 v850ice_kill ()
493 {
494 target_mourn_inferior ();
495 }
496
497 static void
498 v850ice_mourn ()
499 {
500 }
501
502 /* Define the target subroutine names */
503
504 struct target_ops v850ice_ops = {
505 "ice", /* to_shortname */
506 "NEC V850 ICE interface", /* to_longname */
507 "Debug a system controlled by a NEC 850 ICE.", /* to_doc */
508 v850ice_open, /* to_open */
509 v850ice_close, /* to_close */
510 NULL, /* to_attach */
511 v850ice_detach, /* to_detach */
512 v850ice_resume, /* to_resume */
513 v850ice_wait, /* to_wait */
514 v850ice_fetch_registers, /* to_fetch_registers */
515 v850ice_store_registers, /* to_store_registers */
516 v850ice_prepare_to_store, /* to_prepare_to_store */
517 v850ice_xfer_memory, /* to_xfer_memory */
518 v850ice_files_info, /* to_files_info */
519 v850ice_insert_breakpoint, /* to_insert_breakpoint */
520 v850ice_remove_breakpoint, /* to_remove_breakpoint */
521 NULL, /* to_terminal_init */
522 NULL, /* to_terminal_inferior */
523 NULL, /* to_terminal_ours_for_output */
524 NULL, /* to_terminal_ours */
525 NULL, /* to_terminal_info */
526 v850ice_kill, /* to_kill */
527 generic_load, /* to_load */
528 NULL, /* to_lookup_symbol */
529 NULL, /* to_create_inferior */
530 v850ice_mourn, /* to_mourn_inferior */
531 0, /* to_can_run */
532 0, /* to_notice_signals */
533 NULL, /* to_thread_alive */
534 0, /* to_stop */
535 process_stratum, /* to_stratum */
536 NULL, /* to_next */
537 1, /* to_has_all_memory */
538 1, /* to_has_memory */
539 1, /* to_has_stack */
540 1, /* to_has_registers */
541 1, /* to_has_execution */
542 NULL, /* sections */
543 NULL, /* sections_end */
544 OPS_MAGIC /* to_magic */
545 };
546
547 void
548 _initialize_v850ice ()
549 {
550 add_target (&v850ice_ops);
551 }