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"
38 #define WIN32_LEAN_AND_MEAN
41 /* Prototypes for local functions */
43 static void v850ice_files_info
PARAMS ((struct target_ops
*ignore
));
45 static int v850ice_xfer_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
46 int len
, int should_write
,
47 struct target_ops
*target
));
49 static void v850ice_prepare_to_store
PARAMS ((void));
51 static void v850ice_fetch_registers
PARAMS ((int regno
));
53 static void v850ice_resume
PARAMS ((int pid
, int step
,
54 enum target_signal siggnal
));
56 static void v850ice_open
PARAMS ((char *name
, int from_tty
));
58 static void v850ice_close
PARAMS ((int quitting
));
60 static void v850ice_store_registers
PARAMS ((int regno
));
62 static void v850ice_mourn
PARAMS ((void));
64 static int v850ice_wait
PARAMS ((int pid
, struct target_waitstatus
*status
));
66 static void v850ice_kill
PARAMS ((void));
68 static void v850ice_detach
PARAMS ((char *args
, int from_tty
));
70 static int v850ice_insert_breakpoint
PARAMS ((CORE_ADDR
, char *));
72 static int v850ice_remove_breakpoint
PARAMS ((CORE_ADDR
, char *));
74 static int ice_open
= 0;
76 static struct target_ops v850ice_ops
;
79 #define EXPORT __declspec(dllexport)
84 int size
; /* length of input or output in bytes */
85 char *buf
; /* buffer having the input/output information */
88 struct MessageIO null_iob
= { 0, NULL
};
90 EXPORT
long __stdcall
ExeAppReq (char *, long, char *, struct MessageIO
*);
91 EXPORT
long __stdcall
RegisterClient (HWND
);
92 EXPORT
long __stdcall
UnregisterClient (void);
93 EXPORT
long __stdcall
GdbCallBack (void);
95 #define MREADREG 0x0001
96 #define MWRITEREG 0x0002
97 #define MREADMEM 0x0003
98 #define MWRITEMEM 0x0004
99 #define MSINGLESTEP 0x0005
100 #define MRESUME 0x0006
101 #define MLOADPROGRAM 0x0007
102 #define MSETBREAK 0x0008
103 #define MREMOVEBREAK 0x0009
105 #define MTERMINATE 0x000B
106 #define MATTACH 0x000C
107 #define MCHECKSTATUS 0x000D
109 #define MDIRECTCMD 0x000F
110 #define MSYMADR 0x0010
111 #define MGETTASKLIST 0x0011
112 #define MREADVECREG 0x0012
113 #define MWRITEVECREG 0x0013
114 #define MGETCHANGEDREGS 0x0014
115 #define MGETSERVERINFO 0x0015
116 #define MREADBLOCK 0x0016
117 #define MSETHARDBRK 0x0017
118 #define MREMOVEHARDBRK 0x0018
119 #define MCOPYBLOCK 0x0019
120 #define MBLOCKFILL 0x001A
121 #define MFINDBLOCK 0x001B
122 #define MCOMPAREBLOCK 0x001C
123 #define MREFRESH 0x001D
124 #define MSPECIAL 0x001E
125 #define MGETCMDLIST 0x001F
126 #define MEXPVAL 0x0020
127 #define MEXPFAILED 0x0021
128 #define MSAVESTATE 0x0022
129 #define MWRITEBLOCK 0x0023
130 #define MDETACH 0x0024
131 #define MGETMODULES 0x0025
132 #define MREMOTESYMBOL 0x0026
133 #define MREADCSTRING 0x0027
134 #define MLOADMODULE 0x0028
135 #define MDIDSYSCALL 0x0029
136 #define MDBPWRITEBUFFERS 0x002A
138 #define MINITEXEC 0x002C
139 #define MEXITEXEC 0x002D
140 #define MRCCMD 0x002E
141 #define MDOWNLOAD 0x0050
143 #define StatRunning 0
144 #define StatExecBreak 1 /* an execution breakpoint has been reached */
145 #define StatStepped 2 /* a single step has been completed */
146 #define StatException 3 /* the target has stopped due to an exception */
147 #define StatHalted 4 /* target has been halted by a user request */
148 #define StatExited 5 /* target called exit */
149 #define StatTerminated 6 /* target program terminated by a user request */
150 #define StatNoProcess 7 /* no process on target and none of the above */
151 #define StatNeedInput 8 /* REV: obsolete */
152 #define StatNeedDirCmd 9 /* waiting for an entry in the remote window */
153 #define StatHardBreak 10 /* hit hardware breakpoint */
154 #define StatFailure 11 /* an error occured in the last run/single */
157 /* "pir", "tkcw", "chcw", "adtre" */
159 /* Code for opening a connection to the ICE. */
162 v850ice_open (name
, from_tty
)
169 error ("Too many arguments.");
171 target_preopen (from_tty
);
173 unpush_target (&v850ice_ops
);
176 puts_filtered ("V850ice debugging\n");
178 push_target (&v850ice_ops
); /* Switch to using v850ice target now */
180 target_terminal_init ();
182 /* Without this, some commands which require an active target (such as kill)
183 won't work. This variable serves (at least) double duty as both the pid
184 of the target process (if it has such), and as a flag indicating that a
185 target is active. These functions should be split out into seperate
186 variables, especially since GDB will someday have a notion of debugging
187 several processes. */
189 inferior_pid
= 42000;
191 /* Start the v850ice connection; if error (0), discard this target.
192 In particular, if the user quits, be sure to discard it
193 (we'd be in an inconsistent state otherwise). */
195 WinExec ("necsrv", SW_SHOW
); /* Start up necsrv */
197 retval
= RegisterClient (NULL
);
209 error ("v850ice_open: MINITEXEC return error: 0x%x", retval
);
212 /* Clean up connection to a remote debugger. */
216 v850ice_close (quitting
)
224 retval
= ExeAppReq ("GDB", MEXITEXEC
, NULL
, &null_iob
);
226 error ("ExeAppReq (MEXITEXEC) returned %d", retval
);
234 v850ice_detach (args
, from_tty
)
239 error ("Argument given to \"detach\" when remotely debugging.");
243 puts_filtered ("Ending v850ice debugging.\n");
246 /* Tell the remote machine to resume. */
249 v850ice_resume (pid
, step
, siggnal
)
251 enum target_signal siggnal
;
256 retval
= ExeAppReq ("GDB", MSINGLESTEP
, "step", &null_iob
);
258 retval
= ExeAppReq ("GDB", MRESUME
, "run", &null_iob
);
261 error ("ExeAppReq (step = %d) returned %d", step
, retval
);
264 /* Wait until the remote machine stops, then return,
265 storing status in STATUS just as `wait' would.
266 Returns "pid" (though it's not clear what, if anything, that
267 means in the case of this target). */
270 v850ice_wait (pid
, status
)
272 struct target_waitstatus
*status
;
276 v850_status
= ExeAppReq ("GDB", MCHECKSTATUS
, NULL
, &null_iob
);
278 status
->kind
= TARGET_WAITKIND_STOPPED
;
279 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
285 convert_register (regno
, buf
)
290 sprintf (buf
, "r%d", regno
);
291 else if (reg_names
[regno
][0] == 's'
292 && reg_names
[regno
][1] == 'r')
295 sprintf (buf
, "%s", reg_names
[regno
]);
300 /* Read the remote registers into the block REGS. */
301 /* Note that the ICE returns register contents as ascii hex strings. We have
302 to convert that to an unsigned long, and then call store_unsigned_integer to
303 convert it to target byte-order if necessary. */
306 v850ice_fetch_registers (regno
)
312 struct MessageIO iob
;
313 unsigned long regval
;
318 for (regno
= 0; regno
< NUM_REGS
; regno
++)
319 v850ice_fetch_registers (regno
);
323 strcpy (cmd
, "reg ");
324 if (!convert_register (regno
, &cmd
[4]))
327 iob
.size
= sizeof val
;
329 retval
= ExeAppReq ("GDB", MREADREG
, cmd
, &iob
);
331 error ("ExeAppReq returned %d: cmd = %s", retval
, cmd
);
333 regval
= strtoul (val
, &p
, 16);
334 if (regval
== 0 && p
== val
)
335 error ("v850ice_fetch_registers (%d): bad value from ICE: %s.",
338 store_unsigned_integer (val
, REGISTER_RAW_SIZE (regno
), regval
);
339 supply_register (regno
, val
);
342 /* Store register REGNO, or all registers if REGNO == -1, from the contents
346 v850ice_store_registers (regno
)
351 unsigned long regval
;
355 for (regno
= 0; regno
< NUM_REGS
; regno
++)
356 v850ice_store_registers (regno
);
360 regval
= extract_unsigned_integer (®isters
[REGISTER_BYTE (regno
)],
361 REGISTER_RAW_SIZE (regno
));
362 strcpy (cmd
, "reg ");
363 if (!convert_register (regno
, &cmd
[4]))
365 sprintf (cmd
+ strlen (cmd
), "=0x%x", regval
);
367 retval
= ExeAppReq ("GDB", MWRITEREG
, cmd
, &null_iob
);
369 error ("ExeAppReq returned %d: cmd = %s", retval
, cmd
);
372 /* Prepare to store registers. Nothing to do here, since the ICE can write one
373 register at a time. */
376 v850ice_prepare_to_store ()
380 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
381 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
382 nonzero. Returns length of data written or read; 0 for error. */
386 v850ice_xfer_memory (memaddr
, myaddr
, len
, should_write
, target
)
391 struct target_ops
*target
; /* ignored */
395 struct MessageIO iob
;
403 sprintf (cmd
, "memory b c 0x%x=0x00 l=%d", (int)memaddr
, len
);
404 retval
= ExeAppReq ("GDB", MWRITEBLOCK
, cmd
, &iob
);
406 sprintf (cmd
, "memory b c 0x%x=0x%x", (int)memaddr
, *myaddr
& 0xff);
407 retval
= ExeAppReq ("GDB", MWRITEBLOCK
, cmd
, &iob
);
416 tmp
= alloca (len
+ 100);
417 memset (tmp
+ len
, 0xff, 100);
420 sprintf (cmd
, "memory b 0x%x l=%d", (int)memaddr
, len
);
421 retval
= ExeAppReq ("GDB", MREADBLOCK
, cmd
, &iob
);
423 sprintf (cmd
, "memory h 0x%x", (int)memaddr
);
424 retval
= ExeAppReq ("GDB", MREADMEM
, cmd
, &iob
);
426 for (i
= 0; i
< 100; i
++)
428 if (tmp
[len
+ i
] != 0xff)
430 warning ("MREADBLOCK trashed bytes after transfer area.");
434 memcpy (myaddr
, tmp
, len
);
438 error ("ExeAppReq returned %d: cmd = %s", retval
, cmd
);
444 v850ice_files_info (ignore
)
445 struct target_ops
*ignore
;
447 puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
451 v850ice_insert_breakpoint (addr
, contents_cache
)
453 char *contents_cache
;
458 sprintf (cmd
, "%d, ", addr
);
461 retval
= ExeAppReq ("GDB", MSETBREAK
, cmd
, &null_iob
);
463 retval
= ExeAppReq ("GDB", MSETHARDBRK
, cmd
, &null_iob
);
466 error ("ExeAppReq (MSETBREAK) returned %d: cmd = %s", retval
, cmd
);
472 v850ice_remove_breakpoint (addr
, contents_cache
)
474 char *contents_cache
;
479 sprintf (cmd
, "%d, ", addr
);
482 retval
= ExeAppReq ("GDB", MREMOVEBREAK
, cmd
, &null_iob
);
484 retval
= ExeAppReq ("GDB", MREMOVEHARDBRK
, cmd
, &null_iob
);
487 error ("ExeAppReq (MREMOVEBREAK) returned %d: cmd = %s", retval
, cmd
);
495 target_mourn_inferior ();
503 /* Define the target subroutine names */
506 static void init_850ice_ops(void)
508 v850ice_ops
.to_shortname
= "ice";
509 v850ice_ops
.to_longname
= "NEC V850 ICE interface";
510 v850ice_ops
.to_doc
= "Debug a system controlled by a NEC 850 ICE.";
511 v850ice_ops
.to_open
= v850ice_open
;
512 v850ice_ops
.to_close
= v850ice_close
;
513 v850ice_ops
.to_attach
= NULL
;
514 v850ice_ops
.to_detach
= v850ice_detach
;
515 v850ice_ops
.to_resume
= v850ice_resume
;
516 v850ice_ops
.to_wait
= v850ice_wait
;
517 v850ice_ops
.to_fetch_registers
= v850ice_fetch_registers
;
518 v850ice_ops
.to_store_registers
= v850ice_store_registers
;
519 v850ice_ops
.to_prepare_to_store
= v850ice_prepare_to_store
;
520 v850ice_ops
.to_xfer_memory
= v850ice_xfer_memory
;
521 v850ice_ops
.to_files_info
= v850ice_files_info
;
522 v850ice_ops
.to_insert_breakpoint
= v850ice_insert_breakpoint
;
523 v850ice_ops
.to_remove_breakpoint
= v850ice_remove_breakpoint
;
524 v850ice_ops
.to_terminal_init
= NULL
;
525 v850ice_ops
.to_terminal_inferior
= NULL
;
526 v850ice_ops
.to_terminal_ours_for_output
= NULL
;
527 v850ice_ops
.to_terminal_ours
= NULL
;
528 v850ice_ops
.to_terminal_info
= NULL
;
529 v850ice_ops
.to_kill
= v850ice_kill
;
530 v850ice_ops
.to_load
= generic_load
;
531 v850ice_ops
.to_lookup_symbol
= NULL
;
532 v850ice_ops
.to_create_inferior
= NULL
;
533 v850ice_ops
.to_mourn_inferior
= v850ice_mourn
;
534 v850ice_ops
.to_can_run
= 0;
535 v850ice_ops
.to_notice_signals
= 0;
536 v850ice_ops
.to_thread_alive
= NULL
;
537 v850ice_ops
.to_stop
= 0;
538 v850ice_ops
.to_stratum
= process_stratum
;
539 v850ice_ops
.DONT_USE
= NULL
;
540 v850ice_ops
.to_has_all_memory
= 1;
541 v850ice_ops
.to_has_memory
= 1;
542 v850ice_ops
.to_has_stack
= 1;
543 v850ice_ops
.to_has_registers
= 1;
544 v850ice_ops
.to_has_execution
= 1;
545 v850ice_ops
.to_sections
= NULL
;
546 v850ice_ops
.to_sections_end
= NULL
;
547 v850ice_ops
.to_magic
= OPS_MAGIC
;
551 _initialize_v850ice ()
554 add_target (&v850ice_ops
);