1/* ICE interface for the NEC V850 for GDB, the GNU debugger.
2   Copyright 1996, 1997, 1998, 1999, 2000, 2001
3   Free Software Foundation, Inc.
4
5   This file is part of GDB.
6
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 2 of the License, or
10   (at your option) any later version.
11
12   This program is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with this program; if not, write to the Free Software
19   Foundation, Inc., 59 Temple Place - Suite 330,
20   Boston, MA 02111-1307, USA.  */
21
22#include "defs.h"
23#include "gdb_string.h"
24#include "frame.h"
25#include "symtab.h"
26#include "inferior.h"
27#include "breakpoint.h"
28#include "symfile.h"
29#include "target.h"
30#include "objfiles.h"
31#include "gdbcore.h"
32#include "value.h"
33#include "command.h"
34#include "regcache.h"
35
36#include <tcl.h>
37#include <windows.h>
38#include <winuser.h>		/* for WM_USER */
39
40extern unsigned long int strtoul (const char *nptr, char **endptr,
41				  int base);
42
43/* Local data definitions */
44struct MessageIO
45  {
46    int size;			/* length of input or output in bytes         */
47    char *buf;			/* buffer having the input/output information */
48  };
49
50/* Prototypes for functions located in other files */
51extern void break_command (char *, int);
52
53/* Prototypes for local functions */
54static int init_hidden_window (void);
55
56static LRESULT CALLBACK v850ice_wndproc (HWND, UINT, WPARAM, LPARAM);
57
58static void v850ice_files_info (struct target_ops *ignore);
59
60static int v850ice_xfer_memory (CORE_ADDR memaddr, char *myaddr,
61				int len, int should_write,
62				struct target_ops *target);
63
64static void v850ice_prepare_to_store (void);
65
66static void v850ice_fetch_registers (int regno);
67
68static void v850ice_resume (ptid_t ptid, int step,
69                            enum target_signal siggnal);
70
71static void v850ice_open (char *name, int from_tty);
72
73static void v850ice_close (int quitting);
74
75static void v850ice_stop (void);
76
77static void v850ice_store_registers (int regno);
78
79static void v850ice_mourn (void);
80
81static ptid_t v850ice_wait (ptid_t ptid,
82                                  struct target_waitstatus *status);
83
84static void v850ice_kill (void);
85
86static void v850ice_detach (char *args, int from_tty);
87
88static int v850ice_insert_breakpoint (CORE_ADDR, char *);
89
90static int v850ice_remove_breakpoint (CORE_ADDR, char *);
91
92static void v850ice_command (char *, int);
93
94static int ice_disassemble (unsigned long, int, char *);
95
96static int ice_lookup_addr (unsigned long *, char *, char *);
97
98static int ice_lookup_symbol (unsigned long, char *);
99
100static void ice_SimulateDisassemble (char *, int);
101
102static void ice_SimulateAddrLookup (char *, int);
103
104static void ice_Simulate_SymLookup (char *, int);
105
106static void ice_fputs (const char *, struct ui_file *);
107
108static int ice_file (char *);
109
110static int ice_cont (char *);
111
112static int ice_stepi (char *);
113
114static int ice_nexti (char *);
115
116static void togdb_force_update (void);
117
118static void view_source (CORE_ADDR);
119
120static void do_gdb (char *, char *, void (*func) (char *, int), int);
121
122
123/* Globals */
124static HWND hidden_hwnd;	/* HWND for messages */
125
126long (__stdcall * ExeAppReq) (char *, long, char *, struct MessageIO *);
127
128long (__stdcall * RegisterClient) (HWND);
129
130long (__stdcall * UnregisterClient) (void);
131
132extern Tcl_Interp *gdbtk_interp;
133
134/* Globals local to this file only */
135static int ice_open = 0;	/* Is ICE open? */
136
137static char *v850_CB_Result;	/* special char array for saving 'callback' results */
138
139static int SimulateCallback;	/* simulate a callback event */
140
141#define MAX_BLOCK_SIZE    64*1024	/* Cannot transfer memory in blocks bigger
142					   than this */
143/* MDI/ICE Message IDs */
144#define GSINGLESTEP     0x200	/* single-step target          */
145#define GRESUME         0x201	/* resume target               */
146#define GREADREG        0x202	/* read a register             */
147#define GWRITEREG       0x203	/* write a register            */
148#define GWRITEBLOCK     0x204	/* write a block of memory     */
149#define GREADBLOCK      0x205	/* read a block of memory      */
150#define GSETBREAK       0x206	/* set a breakpoint            */
151#define GREMOVEBREAK    0x207	/* remove a breakpoint         */
152#define GHALT           0x208	/* ??? */
153#define GCHECKSTATUS    0x209	/* check status of ICE         */
154#define GMDIREPLY       0x210	/* Reply for previous query - NOT USED */
155#define GDOWNLOAD       0x211	/* something for MDI           */
156#define GCOMMAND        0x212	/* execute command in ice      */
157#define GLOADFILENAME   0x213	/* retrieve load filename      */
158#define GWRITEMEM       0x214	/* write word, half-word, or byte */
159
160/* GCHECKSTATUS return codes: */
161#define ICE_Idle        0x00
162#define ICE_Breakpoint  0x01	/* hit a breakpoint */
163#define ICE_Stepped     0x02	/* have stepped     */
164#define ICE_Exception   0x03	/* have exception   */
165#define ICE_Halted      0x04	/* hit a user halt  */
166#define ICE_Exited      0x05	/* called exit      */
167#define ICE_Terminated  0x06	/* user terminated  */
168#define ICE_Running     0x07
169#define ICE_Unknown     0x99
170
171/* Windows messages */
172#define WM_STATE_CHANGE WM_USER+101
173#define WM_SYM_TO_ADDR  WM_USER+102
174#define WM_ADDR_TO_SYM  WM_USER+103
175#define WM_DISASSEMBLY  WM_USER+104
176#define WM_SOURCE       WM_USER+105
177
178/* STATE_CHANGE codes */
179#define STATE_CHANGE_REGS   1	/* Register(s) changed */
180#define STATE_CHANGE_LOAD   2	/* HW reset            */
181#define STATE_CHANGE_RESET  3	/* Load new file       */
182#define STATE_CHANGE_CONT   4	/* Run target          */
183#define STATE_CHANGE_STOP   5	/* Stop target         */
184#define STATE_CHANGE_STEPI  6	/* Stepi target        */
185#define STATE_CHANGE_NEXTI  7	/* Nexti target        */
186
187static struct target_ops v850ice_ops;	/* Forward decl */
188
189/* This function creates a hidden window */
190static int
191init_hidden_window (void)
192{
193  WNDCLASS class;
194
195  if (hidden_hwnd != NULL)
196    return 1;
197
198  class.style = 0;
199  class.cbClsExtra = 0;
200  class.cbWndExtra = 0;
201  class.hInstance = GetModuleHandle (0);
202  class.hbrBackground = NULL;
203  class.lpszMenuName = NULL;
204  class.lpszClassName = "gdb_v850ice";
205  class.lpfnWndProc = v850ice_wndproc;
206  class.hIcon = NULL;
207  class.hCursor = NULL;
208
209  if (!RegisterClass (&class))
210    return 0;
211
212  hidden_hwnd = CreateWindow ("gdb_v850ice", "gdb_v850ice", WS_TILED,
213			      0, 0, 0, 0, NULL, NULL, class.hInstance,
214			      NULL);
215  if (hidden_hwnd == NULL)
216    {
217      char buf[200];
218      DWORD err;
219
220      err = GetLastError ();
221      FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
222		     0, buf, 200, NULL);
223      printf_unfiltered ("Could not create window: %s", buf);
224      return 0;
225    }
226
227  return 1;
228}
229
230/*
231   This function is installed as the message handler for the hidden window
232   which QBox will use to communicate with gdb. It recognize and acts
233   on the following messages:
234
235   WM_SYM_TO_ADDR  \
236   WM_ADDR_TO_SYM   | Not implemented at NEC's request
237   WM_DISASSEMBLY  /
238   WM_STATE_CHANGE - tells us that a state change has occured in the ICE
239 */
240static LRESULT CALLBACK
241v850ice_wndproc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
242{
243  LRESULT result = FALSE;
244
245  switch (message)
246    {
247    case WM_SYM_TO_ADDR:
248      MessageBox (0, "Symbol resolution\nNot implemented", "GDB", MB_OK);
249      break;
250    case WM_ADDR_TO_SYM:
251      MessageBox (0, "Address resolution\nNot implemented", "GDB", MB_OK);
252      break;
253    case WM_SOURCE:
254      view_source ((CORE_ADDR) lParam);
255      break;
256    case WM_STATE_CHANGE:
257      switch (wParam)
258	{
259	case STATE_CHANGE_LOAD:
260	  {
261	    struct MessageIO iob;
262	    char buf[128];
263
264	    iob.buf = buf;
265	    iob.size = 128;
266
267	    /* Load in a new file... Need filename */
268	    ExeAppReq ("GDB", GLOADFILENAME, NULL, &iob);
269	    if (!catch_errors ((catch_errors_ftype *) ice_file, iob.buf, "", RETURN_MASK_ALL))
270	      printf_unfiltered ("load errored\n");
271	  }
272	  break;
273	case STATE_CHANGE_RESET:
274	  registers_changed ();
275	  flush_cached_frames ();
276	  togdb_force_update ();
277	  result = TRUE;
278	  break;
279	case STATE_CHANGE_REGS:
280	  registers_changed ();
281	  togdb_force_update ();
282	  result = TRUE;
283	  break;
284	case STATE_CHANGE_CONT:
285	  if (!catch_errors ((catch_errors_ftype *) ice_cont, NULL, "", RETURN_MASK_ALL))
286	    printf_unfiltered ("continue errored\n");
287	  result = TRUE;
288	  break;
289	case STATE_CHANGE_STEPI:
290	  if (!catch_errors ((catch_errors_ftype *) ice_stepi, (int) lParam, "",
291			     RETURN_MASK_ALL))
292	    printf_unfiltered ("stepi errored\n");
293	  result = TRUE;
294	  break;
295	case STATE_CHANGE_NEXTI:
296	  if (!catch_errors ((catch_errors_ftype *) ice_nexti, (int) lParam, "",
297			     RETURN_MASK_ALL))
298	    printf_unfiltered ("nexti errored\n");
299	  result = TRUE;
300	  break;
301	}
302    }
303
304  if (result == FALSE)
305    return DefWindowProc (hwnd, message, wParam, lParam);
306
307  return FALSE;
308}
309
310/* Code for opening a connection to the ICE.  */
311
312static void
313v850ice_open (char *name, int from_tty)
314{
315  HINSTANCE handle;
316
317  if (name)
318    error ("Too many arguments.");
319
320  target_preopen (from_tty);
321
322  unpush_target (&v850ice_ops);
323
324  if (from_tty)
325    puts_filtered ("V850ice debugging\n");
326
327  push_target (&v850ice_ops);	/* Switch to using v850ice target now */
328
329  target_terminal_init ();
330
331  /* Initialize everything necessary to facilitate communication
332     between QBox, gdb, and the DLLs which control the ICE */
333  if (ExeAppReq == NULL)
334    {
335      handle = LoadLibrary ("necmsg.dll");
336      if (handle == NULL)
337	error ("Cannot load necmsg.dll");
338
339      ExeAppReq = (long (*) (char *, long, char *, struct MessageIO *))
340	GetProcAddress (handle, "ExeAppReq");
341      RegisterClient = (long (*) (HWND))
342	GetProcAddress (handle, "RegisterClient");
343      UnregisterClient = (long (*) (void))
344	GetProcAddress (handle, "UnregisterClient");
345
346      if (ExeAppReq == NULL || RegisterClient == NULL || UnregisterClient == NULL)
347	error ("Could not find requisite functions in necmsg.dll.");
348
349      if (!init_hidden_window ())
350	error ("could not initialize message handling");
351    }
352
353  /* Tell the DLL we are here */
354  RegisterClient (hidden_hwnd);
355
356  ice_open = 1;
357
358  /* Without this, some commands which require an active target (such as kill)
359     won't work.  This variable serves (at least) double duty as both the pid
360     of the target process (if it has such), and as a flag indicating that a
361     target is active.  These functions should be split out into seperate
362     variables, especially since GDB will someday have a notion of debugging
363     several processes.  */
364  inferior_ptid = pid_to_ptid (42000);
365
366  start_remote ();
367  return;
368}
369
370/* Clean up connection to a remote debugger.  */
371
372static void
373v850ice_close (int quitting)
374{
375  if (ice_open)
376    {
377      UnregisterClient ();
378      ice_open = 0;
379      inferior_ptid = null_ptid;
380    }
381}
382
383/* Stop the process on the ice. */
384static void
385v850ice_stop (void)
386{
387  /* This is silly, but it works... */
388  v850ice_command ("stop", 0);
389}
390
391static void
392v850ice_detach (char *args, int from_tty)
393{
394  if (args)
395    error ("Argument given to \"detach\" when remotely debugging.");
396
397  pop_target ();
398  if (from_tty)
399    puts_filtered ("Ending v850ice debugging.\n");
400}
401
402/* Tell the remote machine to resume.  */
403
404static void
405v850ice_resume (ptid_t ptid, int step, enum target_signal siggnal)
406{
407  long retval;
408  char buf[256];
409  struct MessageIO iob;
410
411  iob.size = 0;
412  iob.buf = buf;
413
414  if (step)
415    retval = ExeAppReq ("GDB", GSINGLESTEP, "step", &iob);
416  else
417    retval = ExeAppReq ("GDB", GRESUME, "run", &iob);
418
419  if (retval)
420    error ("ExeAppReq (step = %d) returned %d", step, retval);
421}
422
423/* Wait until the remote machine stops, then return,
424   storing status in STATUS just as `wait' would.
425   Returns "pid" (though it's not clear what, if anything, that
426   means in the case of this target).  */
427
428static ptid_t
429v850ice_wait (ptid_t ptid, struct target_waitstatus *status)
430{
431  long v850_status;
432  char buf[256];
433  struct MessageIO iob;
434  int done = 0;
435  int count = 0;
436
437  iob.size = 0;
438  iob.buf = buf;
439
440  do
441    {
442      if (count++ % 100000)
443	{
444	  deprecated_ui_loop_hook (0);
445	  count = 0;
446	}
447
448      v850_status = ExeAppReq ("GDB", GCHECKSTATUS, NULL, &iob);
449
450      switch (v850_status)
451	{
452	case ICE_Idle:
453	case ICE_Breakpoint:
454	case ICE_Stepped:
455	case ICE_Halted:
456	  status->kind = TARGET_WAITKIND_STOPPED;
457	  status->value.sig = TARGET_SIGNAL_TRAP;
458	  done = 1;
459	  break;
460	case ICE_Exception:
461	  status->kind = TARGET_WAITKIND_SIGNALLED;
462	  status->value.sig = TARGET_SIGNAL_SEGV;
463	  done = 1;
464	  break;
465	case ICE_Exited:
466	  status->kind = TARGET_WAITKIND_EXITED;
467	  status->value.integer = 0;
468	  done = 1;
469	  break;
470	case ICE_Terminated:
471	  status->kind = TARGET_WAITKIND_SIGNALLED;
472	  status->value.sig = TARGET_SIGNAL_KILL;
473	  done = 1;
474	  break;
475	default:
476	  break;
477	}
478    }
479  while (!done);
480
481  return inferior_ptid;
482}
483
484static int
485convert_register (int regno, char *buf)
486{
487  if (regno <= 31)
488    sprintf (buf, "r%d", regno);
489  else if (REGISTER_NAME (regno)[0] == 's'
490	   && REGISTER_NAME (regno)[1] == 'r')
491    return 0;
492  else
493    sprintf (buf, "%s", REGISTER_NAME (regno));
494
495  return 1;
496}
497
498/* Read the remote registers into the block REGS.  */
499/* Note that the ICE returns register contents as ascii hex strings.  We have
500   to convert that to an unsigned long, and then call store_unsigned_integer to
501   convert it to target byte-order if necessary.  */
502
503static void
504v850ice_fetch_registers (int regno)
505{
506  long retval;
507  char cmd[100];
508  char val[100];
509  struct MessageIO iob;
510  unsigned long regval;
511  char *p;
512
513  if (regno == -1)
514    {
515      for (regno = 0; regno < NUM_REGS; regno++)
516	v850ice_fetch_registers (regno);
517      return;
518    }
519
520  strcpy (cmd, "reg ");
521  if (!convert_register (regno, &cmd[4]))
522    return;
523
524  iob.size = sizeof val;
525  iob.buf = val;
526  retval = ExeAppReq ("GDB", GREADREG, cmd, &iob);
527  if (retval)
528    error ("1: ExeAppReq returned %d: cmd = %s", retval, cmd);
529
530  regval = strtoul (val, NULL, 16);
531  if (regval == 0 && p == val)
532    error ("v850ice_fetch_registers (%d):  bad value from ICE: %s.",
533	   regno, val);
534
535  store_unsigned_integer (val, register_size (current_gdbarch, regno), regval);
536  regcache_raw_supply (current_regcache, regno, val);
537}
538
539/* Store register REGNO, or all registers if REGNO == -1, from the contents
540   of REGISTERS.  */
541
542static void
543v850ice_store_registers (int regno)
544{
545  long retval;
546  char cmd[100];
547  unsigned long regval;
548  char buf[256];
549  struct MessageIO iob;
550  iob.size = 0;
551  iob.buf = buf;
552
553  if (regno == -1)
554    {
555      for (regno = 0; regno < NUM_REGS; regno++)
556	v850ice_store_registers (regno);
557      return;
558    }
559
560  regval = extract_unsigned_integer (&deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)],
561				     register_size (current_gdbarch, regno));
562  strcpy (cmd, "reg ");
563  if (!convert_register (regno, &cmd[4]))
564    return;
565  sprintf (cmd + strlen (cmd), "=0x%x", regval);
566
567  retval = ExeAppReq ("GDB", GWRITEREG, cmd, &iob);
568  if (retval)
569    error ("2: ExeAppReq returned %d: cmd = %s", retval, cmd);
570}
571
572/* Prepare to store registers.  Nothing to do here, since the ICE can write one
573   register at a time.  */
574
575static void
576v850ice_prepare_to_store (void)
577{
578}
579
580/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
581   to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
582   nonzero.  TARGET is unused.  Returns length of data written or read;
583   0 for error.
584
585   We can only read/write MAX_BLOCK_SIZE bytes at a time, though, or the DLL
586   dies.  */
587static int
588v850ice_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
589		     int should_write, struct target_ops *target)
590{
591  long retval;
592  char cmd[100];
593  struct MessageIO iob;
594  int sent;
595
596  if (should_write)
597    {
598      if (len == 4 || len == 2 || len == 1)
599	{
600	  long value = 0;
601	  char buf[256];
602	  char c;
603
604	  iob.size = 0;
605	  iob.buf = buf;
606
607	  sent = 0;
608	  switch (len)
609	    {
610	    case 4:
611	      c = 'w';
612	      value |= (long) ((myaddr[3] << 24) & 0xff000000);
613	      value |= (long) ((myaddr[2] << 16) & 0x00ff0000);
614	      value |= (long) ((myaddr[1] << 8) & 0x0000ff00);
615	      value |= (long) (myaddr[0] & 0x000000ff);
616	      break;
617	    case 2:
618	      c = 'h';
619	      value |= (long) ((myaddr[1] << 8) & 0xff00);
620	      value |= (long) (myaddr[0] & 0x00ff);
621	      break;
622	    case 1:
623	      c = 'b';
624	      value |= (long) (myaddr[0] & 0xff);
625	      break;
626	    }
627
628	  sprintf (cmd, "memory %c c 0x%x=0x%x", c, (int) memaddr, value);
629	  retval = ExeAppReq ("GDB", GWRITEMEM, cmd, &iob);
630	  if (retval == 0)
631	    sent = len;
632	}
633      else
634	{
635	  sent = 0;
636	  do
637	    {
638	      iob.size = len > MAX_BLOCK_SIZE ? MAX_BLOCK_SIZE : len;
639	      iob.buf = myaddr;
640	      sprintf (cmd, "memory b c 0x%x=0x00 l=%d", (int) memaddr, iob.size);
641	      retval = ExeAppReq ("GDB", GWRITEBLOCK, cmd, &iob);
642	      if (retval != 0)
643		break;
644	      len -= iob.size;
645	      memaddr += iob.size;
646	      myaddr += iob.size;
647	      sent += iob.size;
648	    }
649	  while (len > 0);
650	}
651    }
652  else
653    {
654      unsigned char *tmp;
655      unsigned char *t;
656      int i;
657
658      tmp = alloca (len + 100);
659      t = tmp;
660      memset (tmp + len, 0xff, 100);
661
662      sent = 0;
663      do
664	{
665	  iob.size = len > MAX_BLOCK_SIZE ? MAX_BLOCK_SIZE : len;
666	  iob.buf = tmp;
667	  sprintf (cmd, "memory b 0x%x l=%d", (int) memaddr, iob.size);
668	  retval = ExeAppReq ("GDB", GREADBLOCK, cmd, &iob);
669	  if (retval != 0)
670	    break;
671	  len -= iob.size;
672	  memaddr += iob.size;
673	  sent += iob.size;
674	  tmp += iob.size;
675	}
676      while (len > 0);
677
678      if (retval == 0)
679	{
680	  for (i = 0; i < 100; i++)
681	    {
682	      if (t[sent + i] != 0xff)
683		{
684		  warning ("GREADBLOCK trashed bytes after transfer area.");
685		  break;
686		}
687	    }
688	  memcpy (myaddr, t, sent);
689	}
690    }
691
692  if (retval != 0)
693    error ("3: ExeAppReq returned %d: cmd = %s", retval, cmd);
694
695  return sent;
696}
697
698static void
699v850ice_files_info (struct target_ops *ignore)
700{
701  puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
702}
703
704static int
705v850ice_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
706{
707  long retval;
708  char cmd[100];
709  char buf[256];
710  struct MessageIO iob;
711
712  iob.size = 0;
713  iob.buf = buf;
714  sprintf (cmd, "%d, ", addr);
715
716  retval = ExeAppReq ("GDB", GSETBREAK, cmd, &iob);
717  if (retval)
718    error ("ExeAppReq (GSETBREAK) returned %d: cmd = %s", retval, cmd);
719
720  return 0;
721}
722
723static int
724v850ice_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
725{
726  long retval;
727  char cmd[100];
728  char buf[256];
729  struct MessageIO iob;
730
731  iob.size = 0;
732  iob.buf = buf;
733
734  sprintf (cmd, "%d, ", addr);
735
736  retval = ExeAppReq ("GDB", GREMOVEBREAK, cmd, &iob);
737  if (retval)
738    error ("ExeAppReq (GREMOVEBREAK) returned %d: cmd = %s", retval, cmd);
739
740  return 0;
741}
742
743static void
744v850ice_kill (void)
745{
746  target_mourn_inferior ();
747  inferior_ptid = null_ptid;
748}
749
750static void
751v850ice_mourn (void)
752{
753}
754
755static void
756v850ice_load (char *filename, int from_tty)
757{
758  struct MessageIO iob;
759  char buf[256];
760
761  iob.size = 0;
762  iob.buf = buf;
763  generic_load (filename, from_tty);
764  ExeAppReq ("GDB", GDOWNLOAD, filename, &iob);
765}
766
767static int
768ice_file (char *arg)
769{
770  char *s;
771
772  target_detach (NULL, 0);
773  pop_target ();
774
775  printf_unfiltered ("\n");
776
777  s = arg;
778  while (*s != '\0')
779    {
780      if (*s == '\\')
781	*s = '/';
782      s++;
783    }
784
785  /* Safegaurd against confusing the breakpoint routines... */
786  delete_command (NULL, 0);
787
788  /* Must supress from_tty, otherwise we could start asking if the
789     user really wants to load a new symbol table, etc... */
790  printf_unfiltered ("Reading symbols from %s...", arg);
791  exec_open (arg, 0);
792  symbol_file_add_main (arg, 0);
793  printf_unfiltered ("done\n");
794
795  /* exec_open will kill our target, so reinstall the ICE as
796     the target. */
797  v850ice_open (NULL, 0);
798
799  togdb_force_update ();
800  return 1;
801}
802
803static int
804ice_cont (char *c)
805{
806  printf_filtered ("continue (ice)\n");
807  ReplyMessage ((LRESULT) 1);
808
809  if (gdbtk_interp == NULL)
810    {
811      continue_command (NULL, 1);
812    }
813  else
814    Tcl_Eval (gdbtk_interp, "gdb_immediate continue");
815
816  return 1;
817}
818
819static void
820do_gdb (char *cmd, char *str, void (*func) (char *, int), int count)
821{
822  ReplyMessage ((LRESULT) 1);
823
824  while (count--)
825    {
826      printf_unfiltered (str);
827
828      if (gdbtk_interp == NULL)
829	{
830	  func (NULL, 0);
831	}
832      else
833	Tcl_Eval (gdbtk_interp, cmd);
834    }
835}
836
837
838static int
839ice_stepi (char *c)
840{
841  int count = (int) c;
842
843  do_gdb ("gdb_immediate stepi", "stepi (ice)\n", stepi_command, count);
844  return 1;
845}
846
847static int
848ice_nexti (char *c)
849{
850  int count = (int) c;
851
852  do_gdb ("gdb_immediate nexti", "nexti (ice)\n", nexti_command, count);
853  return 1;
854}
855
856static void
857v850ice_command (char *arg, int from_tty)
858{
859  struct MessageIO iob;
860  char buf[256];
861
862  iob.buf = buf;
863  iob.size = 0;
864  ExeAppReq ("GDB", GCOMMAND, arg, &iob);
865}
866
867static void
868togdb_force_update (void)
869{
870  if (gdbtk_interp != NULL)
871    Tcl_Eval (gdbtk_interp, "gdbtk_update");
872}
873
874static void
875view_source (CORE_ADDR addr)
876{
877  char c[256];
878
879  if (gdbtk_interp != NULL)
880    {
881      sprintf (c, "catch {set src [lindex [ManagedWin::find SrcWin] 0]\n$src location BROWSE [gdb_loc *0x%x]}", addr);
882      Tcl_Eval (gdbtk_interp, c);
883    }
884}
885
886/* Define the target subroutine names */
887
888static void
889init_850ice_ops (void)
890{
891  v850ice_ops.to_shortname = "ice";
892  v850ice_ops.to_longname = "NEC V850 ICE interface";
893  v850ice_ops.to_doc = "Debug a system controlled by a NEC 850 ICE.";
894  v850ice_ops.to_open = v850ice_open;
895  v850ice_ops.to_close = v850ice_close;
896  v850ice_ops.to_detach = v850ice_detach;
897  v850ice_ops.to_resume = v850ice_resume;
898  v850ice_ops.to_wait = v850ice_wait;
899  v850ice_ops.to_fetch_registers = v850ice_fetch_registers;
900  v850ice_ops.to_store_registers = v850ice_store_registers;
901  v850ice_ops.to_prepare_to_store = v850ice_prepare_to_store;
902  v850ice_ops.deprecated_xfer_memory = v850ice_xfer_memory;
903  v850ice_ops.to_files_info = v850ice_files_info;
904  v850ice_ops.to_insert_breakpoint = v850ice_insert_breakpoint;
905  v850ice_ops.to_remove_breakpoint = v850ice_remove_breakpoint;
906  v850ice_ops.to_kill = v850ice_kill;
907  v850ice_ops.to_load = v850ice_load;
908  v850ice_ops.to_mourn_inferior = v850ice_mourn;
909  v850ice_ops.to_stop = v850ice_stop;
910  v850ice_ops.to_stratum = process_stratum;
911  v850ice_ops.to_has_all_memory = 1;
912  v850ice_ops.to_has_memory = 1;
913  v850ice_ops.to_has_stack = 1;
914  v850ice_ops.to_has_registers = 1;
915  v850ice_ops.to_has_execution = 1;
916  v850ice_ops.to_magic = OPS_MAGIC;
917}
918
919void
920_initialize_v850ice (void)
921{
922  init_850ice_ops ();
923  add_target (&v850ice_ops);
924
925  add_com ("ice", class_obscure, v850ice_command,
926	   "Send command to ICE");
927}
928