v850 files that weren't being removed if !keep-v850
[deliverable/binutils-gdb.git] / gdb / v850ice.c
CommitLineData
6c310da8
SG
1/* ICE interface for the NEC V850 for GDB, the GNU debugger.
2 Copyright 1996, Free Software Foundation, Inc.
3
4This file is part of GDB.
5
6This program is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2 of the License, or
9(at your option) any later version.
10
11This program is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with this program; if not, write to the Free Software
18Foundation, 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
264b9de0
SG
38#define WIN32_LEAN_AND_MEAN
39#include <windows.h>
6c310da8
SG
40
41/* Prototypes for local functions */
42
43static void v850ice_files_info PARAMS ((struct target_ops *ignore));
44
45static int v850ice_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
46 int len, int should_write,
47 struct target_ops *target));
48
49static void v850ice_prepare_to_store PARAMS ((void));
50
51static void v850ice_fetch_registers PARAMS ((int regno));
52
53static void v850ice_resume PARAMS ((int pid, int step,
54 enum target_signal siggnal));
55
56static void v850ice_open PARAMS ((char *name, int from_tty));
57
58static void v850ice_close PARAMS ((int quitting));
59
60static void v850ice_store_registers PARAMS ((int regno));
61
62static void v850ice_mourn PARAMS ((void));
63
64static int v850ice_wait PARAMS ((int pid, struct target_waitstatus *status));
65
66static void v850ice_kill PARAMS ((void));
67
68static void v850ice_detach PARAMS ((char *args, int from_tty));
69
70static int v850ice_insert_breakpoint PARAMS ((CORE_ADDR, char *));
71
72static int v850ice_remove_breakpoint PARAMS ((CORE_ADDR, char *));
73
74static int ice_open = 0;
75
76#ifndef EXPORT
77#define EXPORT __declspec(dllexport)
78#endif
79
264b9de0
SG
80struct MessageIO
81{
82 int size; /* length of input or output in bytes */
83 char *buf; /* buffer having the input/output information */
84};
85
86struct MessageIO null_iob = { 0, NULL };
87
88EXPORT long __stdcall ExeAppReq (char *, long, char *, struct MessageIO *);
89EXPORT long __stdcall RegisterClient (HWND);
90EXPORT long __stdcall UnregisterClient (void);
91EXPORT long __stdcall GdbCallBack (void);
6c310da8
SG
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
264b9de0
SG
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
6c310da8
SG
154extern struct target_ops v850ice_ops; /* Forward decl */
155
156/* "pir", "tkcw", "chcw", "adtre" */
157
158/* Code for opening a connection to the ICE. */
159
160static void
161v850ice_open (name, from_tty)
162 char *name;
163 int from_tty;
164{
165 long retval;
6c310da8
SG
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
264b9de0
SG
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 }
6c310da8 205
264b9de0 206 pop_target();
6c310da8 207
264b9de0 208 error ("v850ice_open: MINITEXEC return error: 0x%x", retval);
6c310da8
SG
209}
210
211/* Clean up connection to a remote debugger. */
212
213/* ARGSUSED */
214static void
215v850ice_close (quitting)
216 int quitting;
217{
218 long retval;
219
220 if (ice_open)
221 {
264b9de0
SG
222#if 0
223 retval = ExeAppReq ("GDB", MEXITEXEC, NULL, &null_iob);
6c310da8
SG
224 if (retval)
225 error ("ExeAppReq (MEXITEXEC) returned %d", retval);
264b9de0 226#endif
6c310da8 227 ice_open = 0;
264b9de0 228 UnregisterClient ();
6c310da8
SG
229 }
230}
231
232static void
233v850ice_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
247static void
248v850ice_resume (pid, step, siggnal)
249 int pid, step;
250 enum target_signal siggnal;
251{
252 long retval;
6c310da8
SG
253
254 if (step)
264b9de0 255 retval = ExeAppReq ("GDB", MSINGLESTEP, "step", &null_iob);
6c310da8 256 else
264b9de0 257 retval = ExeAppReq ("GDB", MRESUME, "run", &null_iob);
6c310da8
SG
258
259 if (retval)
264b9de0 260 error ("ExeAppReq (step = %d) returned %d", step, retval);
6c310da8
SG
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
268static int
269v850ice_wait (pid, status)
270 int pid;
271 struct target_waitstatus *status;
272{
264b9de0
SG
273 long v850_status;
274
275 v850_status = ExeAppReq ("GDB", MCHECKSTATUS, NULL, &null_iob);
276
6c310da8
SG
277 status->kind = TARGET_WAITKIND_STOPPED;
278 status->value.sig = TARGET_SIGNAL_TRAP;
279
280 return inferior_pid;
281}
282
283static int
284convert_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
304static void
305v850ice_fetch_registers (regno)
306 int regno;
307{
308 long retval;
309 char cmd[100];
310 char val[100];
264b9de0 311 struct MessageIO iob;
6c310da8
SG
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
264b9de0
SG
326 iob.size = sizeof val;
327 iob.buf = val;
328 retval = ExeAppReq ("GDB", MREADREG, cmd, &iob);
6c310da8
SG
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
344static void
345v850ice_store_registers (regno)
346 int regno;
347{
348 long retval;
349 char cmd[100];
6c310da8
SG
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
264b9de0 366 retval = ExeAppReq ("GDB", MWRITEREG, cmd, &null_iob);
6c310da8
SG
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
374static void
375v850ice_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 */
384static int
385v850ice_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];
264b9de0
SG
394 struct MessageIO iob;
395
396 iob.size = len;
397 iob.buf = myaddr;
6c310da8
SG
398
399 if (should_write)
400 {
401#if 1
402 sprintf (cmd, "memory b c 0x%x=0x00 l=%d", (int)memaddr, len);
264b9de0 403 retval = ExeAppReq ("GDB", MWRITEBLOCK, cmd, &iob);
6c310da8
SG
404#else
405 sprintf (cmd, "memory b c 0x%x=0x%x", (int)memaddr, *myaddr & 0xff);
264b9de0 406 retval = ExeAppReq ("GDB", MWRITEBLOCK, cmd, &iob);
6c310da8
SG
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
264b9de0 418#if 1
6c310da8 419 sprintf (cmd, "memory b 0x%x l=%d", (int)memaddr, len);
264b9de0
SG
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
6c310da8
SG
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
442static void
443v850ice_files_info (ignore)
444 struct target_ops *ignore;
445{
446 puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
447}
448
449static int
450v850ice_insert_breakpoint (addr, contents_cache)
451 CORE_ADDR addr;
452 char *contents_cache;
453{
454 long retval;
455 char cmd[100];
6c310da8
SG
456
457 sprintf (cmd, "%d, ", addr);
458
459#if 1
264b9de0 460 retval = ExeAppReq ("GDB", MSETBREAK, cmd, &null_iob);
6c310da8 461#else
264b9de0 462 retval = ExeAppReq ("GDB", MSETHARDBRK, cmd, &null_iob);
6c310da8
SG
463#endif
464 if (retval)
465 error ("ExeAppReq (MSETBREAK) returned %d: cmd = %s", retval, cmd);
466
467 return 0;
468}
469
470static int
471v850ice_remove_breakpoint (addr, contents_cache)
472 CORE_ADDR addr;
473 char *contents_cache;
474{
475 long retval;
476 char cmd[100];
6c310da8
SG
477
478 sprintf (cmd, "%d, ", addr);
479
480#if 1
264b9de0 481 retval = ExeAppReq ("GDB", MREMOVEBREAK, cmd, &null_iob);
6c310da8 482#else
264b9de0 483 retval = ExeAppReq ("GDB", MREMOVEHARDBRK, cmd, &null_iob);
6c310da8
SG
484#endif
485 if (retval)
486 error ("ExeAppReq (MREMOVEBREAK) returned %d: cmd = %s", retval, cmd);
487
488 return 0;
489}
490
491static void
492v850ice_kill ()
493{
494 target_mourn_inferior ();
495}
496
497static void
498v850ice_mourn ()
499{
500}
501
502/* Define the target subroutine names */
503
504struct 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
547void
548_initialize_v850ice ()
549{
550 add_target (&v850ice_ops);
551}
This page took 0.07377 seconds and 4 git commands to generate.