1 /* ICE interface for the NEC V850 for GDB, the GNU debugger.
2 Copyright 1996, Free Software Foundation, Inc.
4 This file is part of GDB.
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.
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.
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. */
21 #include "gdb_string.h"
35 #include "gdb-stabs.h"
36 #include "gdbthread.h"
39 /* Prototypes for local functions */
41 static void v850ice_files_info PARAMS ((struct target_ops *ignore));
43 static int v850ice_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
44 int len, int should_write,
45 struct target_ops *target));
47 static void v850ice_prepare_to_store PARAMS ((void));
49 static void v850ice_fetch_registers PARAMS ((int regno));
51 static void v850ice_resume PARAMS ((int pid, int step,
52 enum target_signal siggnal));
54 static void v850ice_open PARAMS ((char *name, int from_tty));
56 static void v850ice_close PARAMS ((int quitting));
58 static void v850ice_store_registers PARAMS ((int regno));
60 static void v850ice_mourn PARAMS ((void));
62 static int v850ice_wait PARAMS ((int pid, struct target_waitstatus *status));
64 static void v850ice_kill PARAMS ((void));
66 static void v850ice_detach PARAMS ((char *args, int from_tty));
68 static int v850ice_insert_breakpoint PARAMS ((CORE_ADDR, char *));
70 static int v850ice_remove_breakpoint PARAMS ((CORE_ADDR, char *));
72 static int ice_open = 0;
75 #define EXPORT __declspec(dllexport)
78 EXPORT long __stdcall ExeAppReq (char *, long, char *, char *);
80 #define MREADREG 0x0001
81 #define MWRITEREG 0x0002
82 #define MREADMEM 0x0003
83 #define MWRITEMEM 0x0004
84 #define MSINGLESTEP 0x0005
85 #define MRESUME 0x0006
86 #define MLOADPROGRAM 0x0007
87 #define MSETBREAK 0x0008
88 #define MREMOVEBREAK 0x0009
90 #define MTERMINATE 0x000B
91 #define MATTACH 0x000C
92 #define MCHECKSTATUS 0x000D
94 #define MDIRECTCMD 0x000F
95 #define MSYMADR 0x0010
96 #define MGETTASKLIST 0x0011
97 #define MREADVECREG 0x0012
98 #define MWRITEVECREG 0x0013
99 #define MGETCHANGEDREGS 0x0014
100 #define MGETSERVERINFO 0x0015
101 #define MREADBLOCK 0x0016
102 #define MSETHARDBRK 0x0017
103 #define MREMOVEHARDBRK 0x0018
104 #define MCOPYBLOCK 0x0019
105 #define MBLOCKFILL 0x001A
106 #define MFINDBLOCK 0x001B
107 #define MCOMPAREBLOCK 0x001C
108 #define MREFRESH 0x001D
109 #define MSPECIAL 0x001E
110 #define MGETCMDLIST 0x001F
111 #define MEXPVAL 0x0020
112 #define MEXPFAILED 0x0021
113 #define MSAVESTATE 0x0022
114 #define MWRITEBLOCK 0x0023
115 #define MDETACH 0x0024
116 #define MGETMODULES 0x0025
117 #define MREMOTESYMBOL 0x0026
118 #define MREADCSTRING 0x0027
119 #define MLOADMODULE 0x0028
120 #define MDIDSYSCALL 0x0029
121 #define MDBPWRITEBUFFERS 0x002A
123 #define MINITEXEC 0x002C
124 #define MEXITEXEC 0x002D
125 #define MRCCMD 0x002E
126 #define MDOWNLOAD 0x0050
128 extern struct target_ops v850ice_ops; /* Forward decl */
130 /* "pir", "tkcw", "chcw", "adtre" */
132 /* Code for opening a connection to the ICE. */
135 v850ice_open (name, from_tty)
143 error ("Too many arguments.");
145 target_preopen (from_tty);
147 unpush_target (&v850ice_ops);
150 puts_filtered ("V850ice debugging\n");
152 push_target (&v850ice_ops); /* Switch to using v850ice target now */
154 target_terminal_init ();
156 /* Without this, some commands which require an active target (such as kill)
157 won't work. This variable serves (at least) double duty as both the pid
158 of the target process (if it has such), and as a flag indicating that a
159 target is active. These functions should be split out into seperate
160 variables, especially since GDB will someday have a notion of debugging
161 several processes. */
163 inferior_pid = 42000;
165 /* Start the v850ice connection; if error (0), discard this target.
166 In particular, if the user quits, be sure to discard it
167 (we'd be in an inconsistent state otherwise). */
169 retval = ExeAppReq ("GDB", MINITEXEC, "0", retmsg);
177 /* Clean up connection to a remote debugger. */
181 v850ice_close (quitting)
188 retval = ExeAppReq ("GDB", MEXITEXEC, NULL, NULL);
190 error ("ExeAppReq (MEXITEXEC) returned %d", retval);
196 v850ice_detach (args, from_tty)
201 error ("Argument given to \"detach\" when remotely debugging.");
205 puts_filtered ("Ending v850ice debugging.\n");
208 /* Tell the remote machine to resume. */
211 v850ice_resume (pid, step, siggnal)
213 enum target_signal siggnal;
220 retval = ExeAppReq ("GDB", MSINGLESTEP, "step", val);
222 retval = ExeAppReq ("GDB", MRESUME, "run", val);
225 error ("ExeAppReq (step = %d) returned %d: cmd = %s", step, retval, cmd);
228 /* Wait until the remote machine stops, then return,
229 storing status in STATUS just as `wait' would.
230 Returns "pid" (though it's not clear what, if anything, that
231 means in the case of this target). */
234 v850ice_wait (pid, status)
236 struct target_waitstatus *status;
238 status->kind = TARGET_WAITKIND_STOPPED;
239 status->value.sig = TARGET_SIGNAL_TRAP;
245 convert_register (regno, buf)
250 sprintf (buf, "r%d", regno);
251 else if (reg_names[regno][0] == 's'
252 && reg_names[regno][1] == 'r')
255 sprintf (buf, "%s", reg_names[regno]);
260 /* Read the remote registers into the block REGS. */
261 /* Note that the ICE returns register contents as ascii hex strings. We have
262 to convert that to an unsigned long, and then call store_unsigned_integer to
263 convert it to target byte-order if necessary. */
266 v850ice_fetch_registers (regno)
272 unsigned long regval;
277 for (regno = 0; regno < NUM_REGS; regno++)
278 v850ice_fetch_registers (regno);
282 strcpy (cmd, "reg ");
283 if (!convert_register (regno, &cmd[4]))
286 retval = ExeAppReq ("GDB", MREADREG, cmd, val);
288 error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
290 regval = strtoul (val, &p, 16);
291 if (regval == 0 && p == val)
292 error ("v850ice_fetch_registers (%d): bad value from ICE: %s.",
295 store_unsigned_integer (val, REGISTER_RAW_SIZE (regno), regval);
296 supply_register (regno, val);
299 /* Store register REGNO, or all registers if REGNO == -1, from the contents
303 v850ice_store_registers (regno)
309 unsigned long regval;
313 for (regno = 0; regno < NUM_REGS; regno++)
314 v850ice_store_registers (regno);
318 regval = extract_unsigned_integer (®isters[REGISTER_BYTE (regno)],
319 REGISTER_RAW_SIZE (regno));
320 strcpy (cmd, "reg ");
321 if (!convert_register (regno, &cmd[4]))
323 sprintf (cmd + strlen (cmd), "=0x%x", regval);
325 retval = ExeAppReq ("GDB", MWRITEREG, cmd, val);
327 error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
330 /* Prepare to store registers. Nothing to do here, since the ICE can write one
331 register at a time. */
334 v850ice_prepare_to_store ()
338 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
339 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
340 nonzero. Returns length of data written or read; 0 for error. */
344 v850ice_xfer_memory (memaddr, myaddr, len, should_write, target)
349 struct target_ops *target; /* ignored */
357 sprintf (cmd, "memory b c 0x%x=0x00 l=%d", (int)memaddr, len);
358 retval = ExeAppReq ("GDB", MWRITEBLOCK, cmd, myaddr);
360 sprintf (cmd, "memory b c 0x%x=0x%x", (int)memaddr, *myaddr & 0xff);
361 retval = ExeAppReq ("GDB", MWRITEBLOCK, cmd, myaddr);
370 tmp = alloca (len + 100);
371 memset (tmp + len, 0xff, 100);
373 sprintf (cmd, "memory b 0x%x l=%d", (int)memaddr, len);
374 retval = ExeAppReq ("GDB", MREADBLOCK, cmd, tmp);
376 for (i = 0; i < 100; i++)
378 if (tmp[len + i] != 0xff)
380 warning ("MREADBLOCK trashed bytes after transfer area.");
384 memcpy (myaddr, tmp, len);
388 error ("ExeAppReq returned %d: cmd = %s", retval, cmd);
394 v850ice_files_info (ignore)
395 struct target_ops *ignore;
397 puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
401 v850ice_insert_breakpoint (addr, contents_cache)
403 char *contents_cache;
409 sprintf (cmd, "%d, ", addr);
412 retval = ExeAppReq ("GDB", MSETBREAK, cmd, val);
414 retval = ExeAppReq ("GDB", MSETHARDBRK, cmd, val);
417 error ("ExeAppReq (MSETBREAK) returned %d: cmd = %s", retval, cmd);
423 v850ice_remove_breakpoint (addr, contents_cache)
425 char *contents_cache;
431 sprintf (cmd, "%d, ", addr);
434 retval = ExeAppReq ("GDB", MREMOVEBREAK, cmd, val);
436 retval = ExeAppReq ("GDB", MREMOVEHARDBRK, cmd, val);
439 error ("ExeAppReq (MREMOVEBREAK) returned %d: cmd = %s", retval, cmd);
447 target_mourn_inferior ();
455 /* Define the target subroutine names */
457 struct target_ops v850ice_ops = {
458 "ice", /* to_shortname */
459 "NEC V850 ICE interface", /* to_longname */
460 "Debug a system controlled by a NEC 850 ICE.", /* to_doc */
461 v850ice_open, /* to_open */
462 v850ice_close, /* to_close */
463 NULL, /* to_attach */
464 v850ice_detach, /* to_detach */
465 v850ice_resume, /* to_resume */
466 v850ice_wait, /* to_wait */
467 v850ice_fetch_registers, /* to_fetch_registers */
468 v850ice_store_registers, /* to_store_registers */
469 v850ice_prepare_to_store, /* to_prepare_to_store */
470 v850ice_xfer_memory, /* to_xfer_memory */
471 v850ice_files_info, /* to_files_info */
472 v850ice_insert_breakpoint, /* to_insert_breakpoint */
473 v850ice_remove_breakpoint, /* to_remove_breakpoint */
474 NULL, /* to_terminal_init */
475 NULL, /* to_terminal_inferior */
476 NULL, /* to_terminal_ours_for_output */
477 NULL, /* to_terminal_ours */
478 NULL, /* to_terminal_info */
479 v850ice_kill, /* to_kill */
480 generic_load, /* to_load */
481 NULL, /* to_lookup_symbol */
482 NULL, /* to_create_inferior */
483 v850ice_mourn, /* to_mourn_inferior */
485 0, /* to_notice_signals */
486 NULL, /* to_thread_alive */
488 process_stratum, /* to_stratum */
490 1, /* to_has_all_memory */
491 1, /* to_has_memory */
492 1, /* to_has_stack */
493 1, /* to_has_registers */
494 1, /* to_has_execution */
496 NULL, /* sections_end */
497 OPS_MAGIC /* to_magic */
501 _initialize_v850ice ()
503 add_target (&v850ice_ops);