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 Pessublic 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"
25 #include "breakpoint.h"
36 #include <winuser.h> /* for WM_USER */
38 extern unsigned long int strtoul(const char *nptr
, char **endptr
,
41 /* Local data definitions */
44 int size
; /* length of input or output in bytes */
45 char * buf
; /* buffer having the input/output information */
48 /* Prototypes for functions located in other files */
49 extern void break_command
PARAMS ((char *, int));
51 extern void stepi_command
PARAMS ((char *, int));
53 extern void nexti_command
PARAMS ((char *, int));
55 extern void continue_command
PARAMS ((char *, int));
57 extern HINSTANCE Tk_GetHINSTANCE
PARAMS ((void));
59 /* Prototypes for local functions */
60 static int init_hidden_window
PARAMS ((void));
62 static LRESULT CALLBACK v850ice_wndproc
PARAMS ((HWND
, UINT
, WPARAM
, LPARAM
));
64 static void v850ice_files_info
PARAMS ((struct target_ops
*ignore
));
66 static int v850ice_xfer_memory
PARAMS ((CORE_ADDR memaddr
, char *myaddr
,
67 int len
, int should_write
,
68 struct target_ops
*target
));
70 static void v850ice_prepare_to_store
PARAMS ((void));
72 static void v850ice_fetch_registers
PARAMS ((int regno
));
74 static void v850ice_resume
PARAMS ((int pid
, int step
,
75 enum target_signal siggnal
));
77 static void v850ice_open
PARAMS ((char *name
, int from_tty
));
79 static void v850ice_close
PARAMS ((int quitting
));
81 static void v850ice_store_registers
PARAMS ((int regno
));
83 static void v850ice_mourn
PARAMS ((void));
85 static int v850ice_wait
PARAMS ((int pid
, struct target_waitstatus
*status
));
87 static void v850ice_kill
PARAMS ((void));
89 static void v850ice_detach
PARAMS ((char *args
, int from_tty
));
91 static int v850ice_insert_breakpoint
PARAMS ((CORE_ADDR
, char *));
93 static int v850ice_remove_breakpoint
PARAMS ((CORE_ADDR
, char *));
95 static void v850ice_command
PARAMS ((char *, int));
97 static int ice_disassemble
PARAMS ((unsigned long, int, char *));
99 static int ice_lookup_addr
PARAMS ((unsigned long *, char *, char *));
101 static int ice_lookup_symbol
PARAMS ((unsigned long, char *));
103 static void ice_SimulateDisassemble
PARAMS ((char *, int));
105 static void ice_SimulateAddrLookup
PARAMS ((char *, int));
107 static void ice_Simulate_SymLookup
PARAMS ((char *, int));
109 static void ice_fputs
PARAMS ((const char *, GDB_FILE
*));
111 static int ice_file
PARAMS ((char *));
113 static int ice_cont
PARAMS ((char *));
115 static int ice_stepi
PARAMS ((char *));
117 static int ice_nexti
PARAMS ((char *));
119 static void togdb_force_update
PARAMS ((void));
122 static HWND hidden_hwnd
; /* HWND for messages */
124 long (__stdcall
*ExeAppReq
) PARAMS ((char *, long, char *, struct MessageIO
*));
126 long (__stdcall
*RegisterClient
) PARAMS ((HWND
));
128 long (__stdcall
*UnregisterClient
) PARAMS ((void));
130 extern Tcl_Interp
*gdbtk_interp
;
132 /* Globals local to this file only */
133 static int ice_open
= 0; /* Is ICE open? */
135 static char * v850_CB_Result
; /* special char array for saving 'callback' results */
137 static int SimulateCallback
; /* simulate a callback event */
139 #define MAX_BLOCK_SIZE 64*1024 /* Cannot transfer memory in blocks bigger
141 /* MDI/ICE Message IDs */
142 #define GSINGLESTEP 0x200 /* single-step target */
143 #define GRESUME 0x201 /* resume target */
144 #define GREADREG 0x202 /* read a register */
145 #define GWRITEREG 0x203 /* write a register */
146 #define GWRITEBLOCK 0x204 /* write a block of memory */
147 #define GREADBLOCK 0x205 /* read a block of memory */
148 #define GSETBREAK 0x206 /* set a breakpoint */
149 #define GREMOVEBREAK 0x207 /* remove a breakpoint */
150 #define GHALT 0x208 /* ??? */
151 #define GCHECKSTATUS 0x209 /* check status of ICE */
152 #define GMDIREPLY 0x210 /* Reply for previous query - NOT USED */
153 #define GDOWNLOAD 0x211 /* something for MDI */
154 #define GCOMMAND 0x212 /* execute command in ice */
155 #define GLOADFILENAME 0x213 /* retrieve load filename */
156 #define GWRITEMEM 0x214 /* write word, half-word, or byte */
158 /* GCHECKSTATUS return codes: */
159 #define ICE_Idle 0x00
160 #define ICE_Breakpoint 0x01 /* hit a breakpoint */
161 #define ICE_Stepped 0x02 /* have stepped */
162 #define ICE_Exception 0x03 /* have exception */
163 #define ICE_Halted 0x04 /* hit a user halt */
164 #define ICE_Exited 0x05 /* called exit */
165 #define ICE_Terminated 0x06 /* user terminated */
166 #define ICE_Running 0x07
167 #define ICE_Unknown 0x99
169 /* Windows messages */
170 #define WM_STATE_CHANGE WM_USER+101
171 #define WM_SYM_TO_ADDR WM_USER+102
172 #define WM_ADDR_TO_SYM WM_USER+103
173 #define WM_DISASSEMBLY WM_USER+104
175 /* STATE_CHANGE codes */
176 #define STATE_CHANGE_REGS 1 /* Register(s) changed */
177 #define STATE_CHANGE_LOAD 2 /* HW reset */
178 #define STATE_CHANGE_RESET 3 /* Load new file */
179 #define STATE_CHANGE_CONT 4 /* Run target */
180 #define STATE_CHANGE_STOP 5 /* Stop target */
181 #define STATE_CHANGE_STEPI 6 /* Stepi target */
182 #define STATE_CHANGE_NEXTI 7 /* Nexti target */
184 static struct target_ops v850ice_ops
; /* Forward decl */
186 /* This function creates a hidden window */
188 init_hidden_window ()
192 if (hidden_hwnd
!= NULL
)
196 class.cbClsExtra
= 0;
197 class.cbWndExtra
= 0;
198 class.hInstance
= Tk_GetHINSTANCE();
199 class.hbrBackground
= NULL
;
200 class.lpszMenuName
= NULL
;
201 class.lpszClassName
= "gdbtk_v850ice";
202 class.lpfnWndProc
= v850ice_wndproc
;
204 class.hCursor
= NULL
;
206 if (! RegisterClass (&class))
209 hidden_hwnd
= CreateWindow ("gdbtk_v850ice", "gdbtk_v850ice", WS_TILED
,
210 0, 0, 0, 0, NULL
, NULL
, class.hInstance
,
212 if (hidden_hwnd
== NULL
)
217 err
= GetLastError ();
218 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
, NULL
, err
,
220 printf_unfiltered ("Could not create window: %s", buf
);
228 This function is installed as the message handler for the hidden window
229 which QBox will use to communicate with gdbtk. It recognize and acts
230 on the following messages:
233 WM_ADDR_TO_SYM | Not implemented at NEC's request
235 WM_STATE_CHANGE - tells us that a state change has occured in the ICE
237 static LRESULT CALLBACK
238 v850ice_wndproc (hwnd
, message
, wParam
, lParam
)
244 LRESULT result
= FALSE
;
249 MessageBox (0, "Symbol resolution\nNot implemented", "GDB", MB_OK
);
252 MessageBox (0, "Address resolution\nNot implemented", "GDB", MB_OK
);
254 case WM_STATE_CHANGE
:
257 case STATE_CHANGE_LOAD
:
259 struct MessageIO iob
;
265 /* Load in a new file... Need filename */
266 ExeAppReq ("GDB", GLOADFILENAME
, NULL
, &iob
);
267 if (!catch_errors (ice_file
, iob
.buf
, "", RETURN_MASK_ALL
))
268 printf_unfiltered ("load errored\n");
271 case STATE_CHANGE_RESET
:
272 registers_changed ();
273 flush_cached_frames ();
274 togdb_force_update ();
277 case STATE_CHANGE_REGS
:
278 registers_changed ();
279 togdb_force_update ();
282 case STATE_CHANGE_CONT
:
283 if (!catch_errors (ice_cont
, NULL
, "", RETURN_MASK_ALL
))
284 printf_unfiltered ("continue errored\n");
287 case STATE_CHANGE_STEPI
:
288 if (!catch_errors (ice_stepi
, (PTR
)(int) lParam
, "",
290 printf_unfiltered ("stepi errored\n");
293 case STATE_CHANGE_NEXTI
:
294 if (!catch_errors (ice_nexti
, (PTR
)(int) lParam
, "",
296 printf_unfiltered ("nexti errored\n");
303 return DefWindowProc (hwnd
, message
, wParam
, lParam
);
308 /* Code for opening a connection to the ICE. */
311 v850ice_open (name
, from_tty
)
318 error ("Too many arguments.");
320 target_preopen (from_tty
);
322 unpush_target (&v850ice_ops
);
325 puts_filtered ("V850ice debugging\n");
327 push_target (&v850ice_ops
); /* Switch to using v850ice target now */
329 target_terminal_init ();
331 /* Initialize everything necessary to facilitate communication
332 between QBox, gdbtk, and the DLLs which control the ICE */
333 if (ExeAppReq
== NULL
)
335 handle
= LoadLibrary ("necmsg.dll");
337 error ("Cannot load necmsg.dll");
339 ExeAppReq
= (long (*) PARAMS ((char *, long, char *, struct MessageIO
*)))
340 GetProcAddress (handle
, "ExeAppReq");
341 RegisterClient
= (long (*) PARAMS ((HWND
)))
342 GetProcAddress (handle
, "RegisterClient");
343 UnregisterClient
= (long (*) PARAMS ((void)))
344 GetProcAddress (handle
, "UnregisterClient");
346 if (ExeAppReq
== NULL
|| RegisterClient
== NULL
|| UnregisterClient
== NULL
)
347 error ("Could not find requisite functions in necmsg.dll.");
349 if (init_hidden_window () != TCL_OK
)
350 error ("could not initialize message handling");
353 /* Tell the DLL we are here */
354 RegisterClient (hidden_hwnd
);
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_pid
= 42000;
370 /* Clean up connection to a remote debugger. */
374 v850ice_close (quitting
)
386 v850ice_detach (args
, from_tty
)
391 error ("Argument given to \"detach\" when remotely debugging.");
395 puts_filtered ("Ending v850ice debugging.\n");
398 /* Tell the remote machine to resume. */
401 v850ice_resume (pid
, step
, siggnal
)
403 enum target_signal siggnal
;
407 struct MessageIO iob
;
413 retval
= ExeAppReq ("GDB", GSINGLESTEP
, "step", &iob
);
415 retval
= ExeAppReq ("GDB", GRESUME
, "run", &iob
);
418 error ("ExeAppReq (step = %d) returned %d", step
, retval
);
421 /* Wait until the remote machine stops, then return,
422 storing status in STATUS just as `wait' would.
423 Returns "pid" (though it's not clear what, if anything, that
424 means in the case of this target). */
427 v850ice_wait (pid
, status
)
429 struct target_waitstatus
*status
;
433 struct MessageIO iob
;
440 v850_status
= ExeAppReq ("GDB", GCHECKSTATUS
, NULL
, &iob
);
448 status
->kind
= TARGET_WAITKIND_STOPPED
;
449 status
->value
.sig
= TARGET_SIGNAL_TRAP
;
453 status
->kind
= TARGET_WAITKIND_SIGNALLED
;
454 status
->value
.sig
= TARGET_SIGNAL_SEGV
;
458 status
->kind
= TARGET_WAITKIND_EXITED
;
459 status
->value
.integer
= 0;
463 status
->kind
= TARGET_WAITKIND_SIGNALLED
;
464 status
->value
.sig
= TARGET_SIGNAL_KILL
;
477 convert_register (regno
, buf
)
482 sprintf (buf
, "r%d", regno
);
483 else if (reg_names
[regno
][0] == 's'
484 && reg_names
[regno
][1] == 'r')
487 sprintf (buf
, "%s", reg_names
[regno
]);
492 /* Read the remote registers into the block REGS. */
493 /* Note that the ICE returns register contents as ascii hex strings. We have
494 to convert that to an unsigned long, and then call store_unsigned_integer to
495 convert it to target byte-order if necessary. */
498 v850ice_fetch_registers (regno
)
504 struct MessageIO iob
;
505 unsigned long regval
;
510 for (regno
= 0; regno
< NUM_REGS
; regno
++)
511 v850ice_fetch_registers (regno
);
515 strcpy (cmd
, "reg ");
516 if (!convert_register (regno
, &cmd
[4]))
519 iob
.size
= sizeof val
;
521 retval
= ExeAppReq ("GDB", GREADREG
, cmd
, &iob
);
523 error ("1: ExeAppReq returned %d: cmd = %s", retval
, cmd
);
525 regval
= strtoul (val
, NULL
, 16);
526 if (regval
== 0 && p
== val
)
527 error ("v850ice_fetch_registers (%d): bad value from ICE: %s.",
530 store_unsigned_integer (val
, REGISTER_RAW_SIZE (regno
), regval
);
531 supply_register (regno
, val
);
534 /* Store register REGNO, or all registers if REGNO == -1, from the contents
538 v850ice_store_registers (regno
)
543 unsigned long regval
;
545 struct MessageIO iob
;
551 for (regno
= 0; regno
< NUM_REGS
; regno
++)
552 v850ice_store_registers (regno
);
556 regval
= extract_unsigned_integer (®isters
[REGISTER_BYTE (regno
)],
557 REGISTER_RAW_SIZE (regno
));
558 strcpy (cmd
, "reg ");
559 if (!convert_register (regno
, &cmd
[4]))
561 sprintf (cmd
+ strlen (cmd
), "=0x%x", regval
);
563 retval
= ExeAppReq ("GDB", GWRITEREG
, cmd
, &iob
);
565 error ("2: ExeAppReq returned %d: cmd = %s", retval
, cmd
);
568 /* Prepare to store registers. Nothing to do here, since the ICE can write one
569 register at a time. */
572 v850ice_prepare_to_store ()
576 /* Read or write LEN bytes from inferior memory at MEMADDR, transferring
577 to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
578 nonzero. Returns length of data written or read; 0 for error.
580 We can only read/write MAX_BLOCK_SIZE bytes at a time, though, or the DLL
584 v850ice_xfer_memory (memaddr
, myaddr
, len
, should_write
, target
)
589 struct target_ops
*target
; /* ignored */
593 struct MessageIO iob
;
598 if (len
== 4 || len
== 2 || len
== 1)
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;
618 value
|= (long) myaddr
[1] << 8 & 0xff00;
619 value
|= (long) myaddr
[0] & 0x00ff;
623 value
|= (long) myaddr
[0] & 0xff;
627 sprintf (cmd
, "memory %c c 0x%x=0x%x", c
, (int) memaddr
, value
);
628 retval
= ExeAppReq ("GDB", GWRITEMEM
, cmd
, &iob
);
637 iob
.size
= len
> MAX_BLOCK_SIZE
? MAX_BLOCK_SIZE
: len
;
639 sprintf (cmd
, "memory b c 0x%x=0x00 l=%d", (int)memaddr
, iob
.size
);
640 retval
= ExeAppReq ("GDB", GWRITEBLOCK
, cmd
, &iob
);
657 tmp
= alloca (len
+ 100);
659 memset (tmp
+ len
, 0xff, 100);
664 iob
.size
= len
> MAX_BLOCK_SIZE
? MAX_BLOCK_SIZE
: len
;
666 sprintf (cmd
, "memory b 0x%x l=%d", (int)memaddr
, iob
.size
);
667 retval
= ExeAppReq ("GDB", GREADBLOCK
, cmd
, &iob
);
679 for (i
= 0; i
< 100; i
++)
681 if (t
[sent
+ i
] != 0xff)
683 warning ("GREADBLOCK trashed bytes after transfer area.");
687 memcpy (myaddr
, t
, sent
);
692 error ("3: ExeAppReq returned %d: cmd = %s", retval
, cmd
);
698 v850ice_files_info (ignore
)
699 struct target_ops
*ignore
;
701 puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
705 v850ice_insert_breakpoint (addr
, contents_cache
)
707 char *contents_cache
;
712 struct MessageIO iob
;
716 sprintf (cmd
, "%d, ", addr
);
718 retval
= ExeAppReq ("GDB", GSETBREAK
, cmd
, &iob
);
720 error ("ExeAppReq (GSETBREAK) returned %d: cmd = %s", retval
, cmd
);
726 v850ice_remove_breakpoint (addr
, contents_cache
)
728 char *contents_cache
;
733 struct MessageIO iob
;
738 sprintf (cmd
, "%d, ", addr
);
740 retval
= ExeAppReq ("GDB", GREMOVEBREAK
, cmd
, &iob
);
742 error ("ExeAppReq (GREMOVEBREAK) returned %d: cmd = %s", retval
, cmd
);
750 target_mourn_inferior ();
760 v850ice_load (filename
, from_tty
)
764 struct MessageIO iob
;
769 generic_load(filename
, from_tty
);
770 ExeAppReq ("GDB", GDOWNLOAD
, NULL
, &iob
);
779 target_detach (NULL
, 0);
782 printf_unfiltered ("\n");
792 /* Safegaurd against confusing the breakpoint routines... */
793 delete_command(NULL
, 0);
795 /* Must supress from_tty, otherwise we could start asking if the
796 user really wants to load a new symbol table, etc... */
797 printf_unfiltered ("Reading symbols from %s...", arg
);
798 exec_file_command (arg
, 0);
799 symbol_file_command (arg
, 0);
800 printf_unfiltered ("done\n");
802 /* exec_file_command will kill our target, so reinstall the ICE as
804 v850ice_open (NULL
, 0);
806 togdb_force_update ();
814 printf_unfiltered ("continue (ice)\n");
815 continue_command (NULL
, 1);
816 togdb_force_update ();
824 char count_string
[10] = "\0";
827 sprintf (count_string
, "%d", count
);
829 printf_unfiltered ("stepi (ice)\n");
830 stepi_command (count_string
, 1);
831 ReplyMessage ((LRESULT
) 1);
832 togdb_force_update ();
840 char count_string
[10] = "\0";
843 sprintf (count_string
, "%d", count
);
845 printf_unfiltered ("nexti (ice)\n");
846 nexti_command (count_string
, 1);
847 togdb_force_update ();
852 v850ice_command (arg
, from_tty
)
856 struct MessageIO iob
;
861 ExeAppReq ("GDB", GCOMMAND
, arg
, &iob
);
865 togdb_force_update (void)
867 Tcl_Eval (gdbtk_interp
, "gdbtk_update");
870 /* Define the target subroutine names */
872 static void init_850ice_ops(void)
874 v850ice_ops
.to_shortname
= "ice";
875 v850ice_ops
.to_longname
= "NEC V850 ICE interface";
876 v850ice_ops
.to_doc
= "Debug a system controlled by a NEC 850 ICE.";
877 v850ice_ops
.to_open
= v850ice_open
;
878 v850ice_ops
.to_close
= v850ice_close
;
879 v850ice_ops
.to_attach
= NULL
;
880 v850ice_ops
.to_detach
= v850ice_detach
;
881 v850ice_ops
.to_resume
= v850ice_resume
;
882 v850ice_ops
.to_wait
= v850ice_wait
;
883 v850ice_ops
.to_fetch_registers
= v850ice_fetch_registers
;
884 v850ice_ops
.to_store_registers
= v850ice_store_registers
;
885 v850ice_ops
.to_prepare_to_store
= v850ice_prepare_to_store
;
886 v850ice_ops
.to_xfer_memory
= v850ice_xfer_memory
;
887 v850ice_ops
.to_files_info
= v850ice_files_info
;
888 v850ice_ops
.to_insert_breakpoint
= v850ice_insert_breakpoint
;
889 v850ice_ops
.to_remove_breakpoint
= v850ice_remove_breakpoint
;
890 v850ice_ops
.to_terminal_init
= NULL
;
891 v850ice_ops
.to_terminal_inferior
= NULL
;
892 v850ice_ops
.to_terminal_ours_for_output
= NULL
;
893 v850ice_ops
.to_terminal_ours
= NULL
;
894 v850ice_ops
.to_terminal_info
= NULL
;
895 v850ice_ops
.to_kill
= v850ice_kill
;
896 v850ice_ops
.to_load
= v850ice_load
;
897 v850ice_ops
.to_lookup_symbol
= NULL
;
898 v850ice_ops
.to_create_inferior
= NULL
;
899 v850ice_ops
.to_mourn_inferior
= v850ice_mourn
;
900 v850ice_ops
.to_can_run
= 0;
901 v850ice_ops
.to_notice_signals
= 0;
902 v850ice_ops
.to_thread_alive
= NULL
;
903 v850ice_ops
.to_stop
= 0;
904 v850ice_ops
.to_stratum
= process_stratum
;
905 v850ice_ops
.DONT_USE
= NULL
;
906 v850ice_ops
.to_has_all_memory
= 1;
907 v850ice_ops
.to_has_memory
= 1;
908 v850ice_ops
.to_has_stack
= 1;
909 v850ice_ops
.to_has_registers
= 1;
910 v850ice_ops
.to_has_execution
= 1;
911 v850ice_ops
.to_sections
= NULL
;
912 v850ice_ops
.to_sections_end
= NULL
;
913 v850ice_ops
.to_magic
= OPS_MAGIC
;
917 _initialize_v850ice ()
920 add_target (&v850ice_ops
);
922 add_com ("ice", class_obscure
, v850ice_command
,
923 "Send command to ICE");