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