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