xref: /openbsd-src/gnu/usr.bin/binutils/gdb/remote-e7000.c (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1b725ae77Skettenis /* Remote debugging interface for Renesas E7000 ICE, for GDB
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
4*63addd46Skettenis    2002, 2003, 2004 Free Software Foundation, Inc.
5b725ae77Skettenis 
6e93f7393Sniklas    Contributed by Cygnus Support.
7e93f7393Sniklas 
8e93f7393Sniklas    Written by Steve Chamberlain for Cygnus Support.
9e93f7393Sniklas 
10e93f7393Sniklas    This file is part of GDB.
11e93f7393Sniklas 
12e93f7393Sniklas    This program is free software; you can redistribute it and/or modify
13e93f7393Sniklas    it under the terms of the GNU General Public License as published by
14e93f7393Sniklas    the Free Software Foundation; either version 2 of the License, or
15e93f7393Sniklas    (at your option) any later version.
16e93f7393Sniklas 
17e93f7393Sniklas    This program is distributed in the hope that it will be useful,
18e93f7393Sniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
19e93f7393Sniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20e93f7393Sniklas    GNU General Public License for more details.
21e93f7393Sniklas 
22e93f7393Sniklas    You should have received a copy of the GNU General Public License
23e93f7393Sniklas    along with this program; if not, write to the Free Software
24b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
25b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
26e93f7393Sniklas 
27b725ae77Skettenis /* The E7000 is an in-circuit emulator for the Renesas H8/300-H and
28b725ae77Skettenis    Renesas-SH processor.  It has serial port and a lan port.
29e93f7393Sniklas 
30e93f7393Sniklas    The monitor command set makes it difficult to load large ammounts of
31e93f7393Sniklas    data over the lan without using ftp - so try not to issue load
32e93f7393Sniklas    commands when communicating over ethernet; use the ftpload command.
33e93f7393Sniklas 
34e93f7393Sniklas    The monitor pauses for a second when dumping srecords to the serial
35e93f7393Sniklas    line too, so we use a slower per byte mechanism but without the
36e93f7393Sniklas    startup overhead.  Even so, it's pretty slow... */
37e93f7393Sniklas 
38e93f7393Sniklas #include "defs.h"
39e93f7393Sniklas #include "gdbcore.h"
40b725ae77Skettenis #include "gdbarch.h"
41e93f7393Sniklas #include "inferior.h"
42e93f7393Sniklas #include "target.h"
43e93f7393Sniklas #include "value.h"
44e93f7393Sniklas #include "command.h"
45e93f7393Sniklas #include "gdb_string.h"
46e93f7393Sniklas #include "gdbcmd.h"
47e93f7393Sniklas #include <sys/types.h>
48e93f7393Sniklas #include "serial.h"
49e93f7393Sniklas #include "remote-utils.h"
50e93f7393Sniklas #include "symfile.h"
51b725ae77Skettenis #include "regcache.h"
52e93f7393Sniklas #include <time.h>
53b725ae77Skettenis #include <ctype.h>
54b725ae77Skettenis 
55e93f7393Sniklas 
56e93f7393Sniklas #if 1
57e93f7393Sniklas #define HARD_BREAKPOINTS	/* Now handled by set option. */
58e93f7393Sniklas #define BC_BREAKPOINTS use_hard_breakpoints
59e93f7393Sniklas #endif
60e93f7393Sniklas 
61e93f7393Sniklas #define CTRLC 0x03
62e93f7393Sniklas #define ENQ  0x05
63e93f7393Sniklas #define ACK  0x06
64e93f7393Sniklas #define CTRLZ 0x1a
65e93f7393Sniklas 
66b725ae77Skettenis /* This file is used by 2 different targets, sh-elf and h8300. The
67b725ae77Skettenis    h8300 is not multiarched and doesn't use the registers defined in
68b725ae77Skettenis    tm-sh.h. To avoid using a macro GDB_TARGET_IS_SH, we do runtime check
69b725ae77Skettenis    of the target, which requires that these namse below are always
70b725ae77Skettenis    defined also in the h8300 case. */
71b725ae77Skettenis 
72b725ae77Skettenis #if !defined (PR_REGNUM)
73b725ae77Skettenis #define PR_REGNUM 	-1
74b725ae77Skettenis #endif
75b725ae77Skettenis #if !defined (GBR_REGNUM)
76b725ae77Skettenis #define GBR_REGNUM 	-1
77b725ae77Skettenis #endif
78b725ae77Skettenis #if !defined (VBR_REGNUM)
79b725ae77Skettenis #define VBR_REGNUM 	-1
80b725ae77Skettenis #endif
81b725ae77Skettenis #if !defined (MACH_REGNUM)
82b725ae77Skettenis #define MACH_REGNUM 	-1
83b725ae77Skettenis #endif
84b725ae77Skettenis #if !defined (MACL_REGNUM)
85b725ae77Skettenis #define MACL_REGNUM 	-1
86b725ae77Skettenis #endif
87b725ae77Skettenis #if !defined (SR_REGNUM)
88b725ae77Skettenis #define SR_REGNUM 	-1
89b725ae77Skettenis #endif
90b725ae77Skettenis 
91b725ae77Skettenis extern void report_transfer_performance (unsigned long, time_t, time_t);
92e93f7393Sniklas 
93e93f7393Sniklas extern char *sh_processor_type;
94e93f7393Sniklas 
95e93f7393Sniklas /* Local function declarations.  */
96e93f7393Sniklas 
97b725ae77Skettenis static void e7000_close (int);
98e93f7393Sniklas 
99b725ae77Skettenis static void e7000_fetch_register (int);
100e93f7393Sniklas 
101b725ae77Skettenis static void e7000_store_register (int);
102e93f7393Sniklas 
103b725ae77Skettenis static void e7000_command (char *, int);
104e93f7393Sniklas 
105b725ae77Skettenis static void e7000_login_command (char *, int);
106e93f7393Sniklas 
107b725ae77Skettenis static void e7000_ftp_command (char *, int);
108e93f7393Sniklas 
109b725ae77Skettenis static void e7000_drain_command (char *, int);
110e93f7393Sniklas 
111b725ae77Skettenis static void expect (char *);
112e93f7393Sniklas 
113b725ae77Skettenis static void expect_full_prompt (void);
114e93f7393Sniklas 
115b725ae77Skettenis static void expect_prompt (void);
116e93f7393Sniklas 
117b725ae77Skettenis static int e7000_parse_device (char *args, char *dev_name, int baudrate);
118e93f7393Sniklas /* Variables. */
119e93f7393Sniklas 
120b725ae77Skettenis static struct serial *e7000_desc;
121e93f7393Sniklas 
122e93f7393Sniklas /* Allow user to chose between using hardware breakpoints or memory. */
123e93f7393Sniklas static int use_hard_breakpoints = 0;	/* use sw breakpoints by default */
124e93f7393Sniklas 
125e93f7393Sniklas /* Nonzero if using the tcp serial driver.  */
126e93f7393Sniklas 
127e93f7393Sniklas static int using_tcp;		/* direct tcp connection to target */
128e93f7393Sniklas static int using_tcp_remote;	/* indirect connection to target
129e93f7393Sniklas 				   via tcp to controller */
130e93f7393Sniklas 
131e93f7393Sniklas /* Nonzero if using the pc isa card.  */
132e93f7393Sniklas 
133e93f7393Sniklas static int using_pc;
134e93f7393Sniklas 
135e93f7393Sniklas extern struct target_ops e7000_ops;	/* Forward declaration */
136e93f7393Sniklas 
137e93f7393Sniklas char *ENQSTRING = "\005";
138e93f7393Sniklas 
139e93f7393Sniklas /* Nonzero if some routine (as opposed to the user) wants echoing.
140e93f7393Sniklas    FIXME: Do this reentrantly with an extra parameter.  */
141e93f7393Sniklas 
142e93f7393Sniklas static int echo;
143e93f7393Sniklas 
144e93f7393Sniklas static int ctrl_c;
145e93f7393Sniklas 
146e93f7393Sniklas static int timeout = 20;
147e93f7393Sniklas 
148e93f7393Sniklas /* Send data to e7000debug.  */
149e93f7393Sniklas 
150e93f7393Sniklas static void
puts_e7000debug(char * buf)151b725ae77Skettenis puts_e7000debug (char *buf)
152e93f7393Sniklas {
153e93f7393Sniklas   if (!e7000_desc)
154e93f7393Sniklas     error ("Use \"target e7000 ...\" first.");
155e93f7393Sniklas 
156e93f7393Sniklas   if (remote_debug)
157b725ae77Skettenis     printf_unfiltered ("Sending %s\n", buf);
158e93f7393Sniklas 
159b725ae77Skettenis   if (serial_write (e7000_desc, buf, strlen (buf)))
160b725ae77Skettenis     fprintf_unfiltered (gdb_stderr, "serial_write failed: %s\n", safe_strerror (errno));
161e93f7393Sniklas 
162e93f7393Sniklas   /* And expect to see it echoed, unless using the pc interface */
163e93f7393Sniklas #if 0
164e93f7393Sniklas   if (!using_pc)
165e93f7393Sniklas #endif
166e93f7393Sniklas     expect (buf);
167e93f7393Sniklas }
168e93f7393Sniklas 
169e93f7393Sniklas static void
putchar_e7000(int x)170b725ae77Skettenis putchar_e7000 (int x)
171e93f7393Sniklas {
172e93f7393Sniklas   char b[1];
173e93f7393Sniklas 
174e93f7393Sniklas   b[0] = x;
175b725ae77Skettenis   serial_write (e7000_desc, b, 1);
176e93f7393Sniklas }
177e93f7393Sniklas 
178e93f7393Sniklas static void
write_e7000(char * s)179b725ae77Skettenis write_e7000 (char *s)
180e93f7393Sniklas {
181b725ae77Skettenis   serial_write (e7000_desc, s, strlen (s));
182e93f7393Sniklas }
183e93f7393Sniklas 
184e93f7393Sniklas static int
normal(int x)185b725ae77Skettenis normal (int x)
186e93f7393Sniklas {
187e93f7393Sniklas   if (x == '\n')
188e93f7393Sniklas     return '\r';
189e93f7393Sniklas   return x;
190e93f7393Sniklas }
191e93f7393Sniklas 
192e93f7393Sniklas /* Read a character from the remote system, doing all the fancy timeout
193b725ae77Skettenis    stuff.  Handles serial errors and EOF.  If TIMEOUT == 0, and no chars,
194b725ae77Skettenis    returns -1, else returns next char.  Discards chars > 127.  */
195e93f7393Sniklas 
196e93f7393Sniklas static int
readchar(int timeout)197b725ae77Skettenis readchar (int timeout)
198e93f7393Sniklas {
199e93f7393Sniklas   int c;
200e93f7393Sniklas 
201e93f7393Sniklas   do
202e93f7393Sniklas     {
203b725ae77Skettenis       c = serial_readchar (e7000_desc, timeout);
204e93f7393Sniklas     }
205e93f7393Sniklas   while (c > 127);
206e93f7393Sniklas 
207e93f7393Sniklas   if (c == SERIAL_TIMEOUT)
208e93f7393Sniklas     {
209e93f7393Sniklas       if (timeout == 0)
210e93f7393Sniklas 	return -1;
211e93f7393Sniklas       echo = 0;
212e93f7393Sniklas       error ("Timeout reading from remote system.");
213e93f7393Sniklas     }
214b725ae77Skettenis   else if (c < 0)
215b725ae77Skettenis     error ("Serial communication error");
216b725ae77Skettenis 
217e93f7393Sniklas   if (remote_debug)
218e93f7393Sniklas     {
219b725ae77Skettenis       putchar_unfiltered (c);
220b725ae77Skettenis       gdb_flush (gdb_stdout);
221e93f7393Sniklas     }
222e93f7393Sniklas 
223e93f7393Sniklas   return normal (c);
224e93f7393Sniklas }
225e93f7393Sniklas 
226e93f7393Sniklas #if 0
227e93f7393Sniklas char *
228b725ae77Skettenis tl (int x)
229e93f7393Sniklas {
230e93f7393Sniklas   static char b[8][10];
231e93f7393Sniklas   static int p;
232e93f7393Sniklas 
233e93f7393Sniklas   p++;
234e93f7393Sniklas   p &= 7;
235e93f7393Sniklas   if (x >= ' ')
236e93f7393Sniklas     {
237e93f7393Sniklas       b[p][0] = x;
238e93f7393Sniklas       b[p][1] = 0;
239e93f7393Sniklas     }
240e93f7393Sniklas   else
241e93f7393Sniklas     {
242e93f7393Sniklas       sprintf (b[p], "<%d>", x);
243e93f7393Sniklas     }
244e93f7393Sniklas 
245e93f7393Sniklas   return b[p];
246e93f7393Sniklas }
247e93f7393Sniklas #endif
248e93f7393Sniklas 
249e93f7393Sniklas /* Scan input from the remote system, until STRING is found.  If
250e93f7393Sniklas    DISCARD is non-zero, then discard non-matching input, else print it
251e93f7393Sniklas    out.  Let the user break out immediately.  */
252e93f7393Sniklas 
253e93f7393Sniklas static void
expect(char * string)254b725ae77Skettenis expect (char *string)
255e93f7393Sniklas {
256e93f7393Sniklas   char *p = string;
257e93f7393Sniklas   int c;
258e93f7393Sniklas   int nl = 0;
259e93f7393Sniklas 
260e93f7393Sniklas   while (1)
261e93f7393Sniklas     {
262e93f7393Sniklas       c = readchar (timeout);
263e93f7393Sniklas 
264b725ae77Skettenis       if (echo)
265e93f7393Sniklas 	{
266e93f7393Sniklas 	  if (c == '\r' || c == '\n')
267e93f7393Sniklas 	    {
268e93f7393Sniklas 	      if (!nl)
269b725ae77Skettenis 		putchar_unfiltered ('\n');
270e93f7393Sniklas 	      nl = 1;
271e93f7393Sniklas 	    }
272e93f7393Sniklas 	  else
273e93f7393Sniklas 	    {
274e93f7393Sniklas 	      nl = 0;
275b725ae77Skettenis 	      putchar_unfiltered (c);
276e93f7393Sniklas 	    }
277b725ae77Skettenis 	  gdb_flush (gdb_stdout);
278e93f7393Sniklas 	}
279e93f7393Sniklas       if (normal (c) == normal (*p++))
280e93f7393Sniklas 	{
281e93f7393Sniklas 	  if (*p == '\0')
282e93f7393Sniklas 	    return;
283e93f7393Sniklas 	}
284e93f7393Sniklas       else
285e93f7393Sniklas 	{
286e93f7393Sniklas 	  p = string;
287e93f7393Sniklas 
288e93f7393Sniklas 	  if (normal (c) == normal (string[0]))
289e93f7393Sniklas 	    p++;
290e93f7393Sniklas 	}
291e93f7393Sniklas     }
292e93f7393Sniklas }
293e93f7393Sniklas 
294e93f7393Sniklas /* Keep discarding input until we see the e7000 prompt.
295e93f7393Sniklas 
296e93f7393Sniklas    The convention for dealing with the prompt is that you
297e93f7393Sniklas    o give your command
298e93f7393Sniklas    o *then* wait for the prompt.
299e93f7393Sniklas 
300e93f7393Sniklas    Thus the last thing that a procedure does with the serial line will
301e93f7393Sniklas    be an expect_prompt().  Exception: e7000_resume does not wait for
302e93f7393Sniklas    the prompt, because the terminal is being handed over to the
303e93f7393Sniklas    inferior.  However, the next thing which happens after that is a
304e93f7393Sniklas    e7000_wait which does wait for the prompt.  Note that this includes
305e93f7393Sniklas    abnormal exit, e.g. error().  This is necessary to prevent getting
306e93f7393Sniklas    into states from which we can't recover.  */
307e93f7393Sniklas 
308e93f7393Sniklas static void
expect_prompt(void)309b725ae77Skettenis expect_prompt (void)
310e93f7393Sniklas {
311e93f7393Sniklas   expect (":");
312e93f7393Sniklas }
313e93f7393Sniklas 
314e93f7393Sniklas static void
expect_full_prompt(void)315b725ae77Skettenis expect_full_prompt (void)
316e93f7393Sniklas {
317e93f7393Sniklas   expect ("\r:");
318e93f7393Sniklas }
319e93f7393Sniklas 
320e93f7393Sniklas static int
convert_hex_digit(int ch)321b725ae77Skettenis convert_hex_digit (int ch)
322e93f7393Sniklas {
323e93f7393Sniklas   if (ch >= '0' && ch <= '9')
324e93f7393Sniklas     return ch - '0';
325e93f7393Sniklas   else if (ch >= 'A' && ch <= 'F')
326e93f7393Sniklas     return ch - 'A' + 10;
327e93f7393Sniklas   else if (ch >= 'a' && ch <= 'f')
328e93f7393Sniklas     return ch - 'a' + 10;
329e93f7393Sniklas   return -1;
330e93f7393Sniklas }
331e93f7393Sniklas 
332e93f7393Sniklas static int
get_hex(int * start)333b725ae77Skettenis get_hex (int *start)
334e93f7393Sniklas {
335e93f7393Sniklas   int value = convert_hex_digit (*start);
336e93f7393Sniklas   int try;
337e93f7393Sniklas 
338e93f7393Sniklas   *start = readchar (timeout);
339e93f7393Sniklas   while ((try = convert_hex_digit (*start)) >= 0)
340e93f7393Sniklas     {
341e93f7393Sniklas       value <<= 4;
342e93f7393Sniklas       value += try;
343e93f7393Sniklas       *start = readchar (timeout);
344e93f7393Sniklas     }
345e93f7393Sniklas   return value;
346e93f7393Sniklas }
347e93f7393Sniklas 
348e93f7393Sniklas #if 0
349e93f7393Sniklas /* Get N 32-bit words from remote, each preceded by a space, and put
350e93f7393Sniklas    them in registers starting at REGNO.  */
351e93f7393Sniklas 
352e93f7393Sniklas static void
353b725ae77Skettenis get_hex_regs (int n, int regno)
354e93f7393Sniklas {
355e93f7393Sniklas   long val;
356e93f7393Sniklas   int i;
357e93f7393Sniklas 
358e93f7393Sniklas   for (i = 0; i < n; i++)
359e93f7393Sniklas     {
360e93f7393Sniklas       int j;
361e93f7393Sniklas 
362e93f7393Sniklas       val = 0;
363e93f7393Sniklas       for (j = 0; j < 8; j++)
364e93f7393Sniklas 	val = (val << 4) + get_hex_digit (j == 0);
365*63addd46Skettenis       regcache_raw_supply (current_regcache, regno++, (char *) &val);
366e93f7393Sniklas     }
367e93f7393Sniklas }
368e93f7393Sniklas #endif
369e93f7393Sniklas 
370e93f7393Sniklas /* This is called not only when we first attach, but also when the
371e93f7393Sniklas    user types "run" after having attached.  */
372e93f7393Sniklas 
373e93f7393Sniklas static void
e7000_create_inferior(char * execfile,char * args,char ** env,int from_tty)374*63addd46Skettenis e7000_create_inferior (char *execfile, char *args, char **env,
375*63addd46Skettenis 		       int from_tty)
376e93f7393Sniklas {
377e93f7393Sniklas   int entry_pt;
378e93f7393Sniklas 
379e93f7393Sniklas   if (args && *args)
380e93f7393Sniklas     error ("Can't pass arguments to remote E7000DEBUG process");
381e93f7393Sniklas 
382e93f7393Sniklas   if (execfile == 0 || exec_bfd == 0)
383b725ae77Skettenis     error ("No executable file specified");
384e93f7393Sniklas 
385e93f7393Sniklas   entry_pt = (int) bfd_get_start_address (exec_bfd);
386e93f7393Sniklas 
387e93f7393Sniklas #ifdef CREATE_INFERIOR_HOOK
388e93f7393Sniklas   CREATE_INFERIOR_HOOK (0);	/* No process-ID */
389e93f7393Sniklas #endif
390e93f7393Sniklas 
391e93f7393Sniklas   /* The "process" (board) is already stopped awaiting our commands, and
392e93f7393Sniklas      the program is already downloaded.  We just set its PC and go.  */
393e93f7393Sniklas 
394e93f7393Sniklas   clear_proceed_status ();
395e93f7393Sniklas 
396e93f7393Sniklas   /* Tell wait_for_inferior that we've started a new process.  */
397e93f7393Sniklas   init_wait_for_inferior ();
398e93f7393Sniklas 
399e93f7393Sniklas   /* Set up the "saved terminal modes" of the inferior
400e93f7393Sniklas      based on what modes we are starting it with.  */
401e93f7393Sniklas   target_terminal_init ();
402e93f7393Sniklas 
403e93f7393Sniklas   /* Install inferior's terminal modes.  */
404e93f7393Sniklas   target_terminal_inferior ();
405e93f7393Sniklas 
406e93f7393Sniklas   /* insert_step_breakpoint ();  FIXME, do we need this?  */
407e93f7393Sniklas   proceed ((CORE_ADDR) entry_pt, -1, 0);	/* Let 'er rip... */
408e93f7393Sniklas }
409e93f7393Sniklas 
410e93f7393Sniklas /* Open a connection to a remote debugger.  NAME is the filename used
411e93f7393Sniklas    for communication.  */
412e93f7393Sniklas 
413e93f7393Sniklas static int baudrate = 9600;
414e93f7393Sniklas static char dev_name[100];
415e93f7393Sniklas 
416e93f7393Sniklas static char *machine = "";
417e93f7393Sniklas static char *user = "";
418e93f7393Sniklas static char *passwd = "";
419e93f7393Sniklas static char *dir = "";
420e93f7393Sniklas 
421e93f7393Sniklas /* Grab the next token and buy some space for it */
422e93f7393Sniklas 
423e93f7393Sniklas static char *
next(char ** ptr)424b725ae77Skettenis next (char **ptr)
425e93f7393Sniklas {
426e93f7393Sniklas   char *p = *ptr;
427e93f7393Sniklas   char *s;
428e93f7393Sniklas   char *r;
429e93f7393Sniklas   int l = 0;
430e93f7393Sniklas 
431e93f7393Sniklas   while (*p && *p == ' ')
432e93f7393Sniklas     p++;
433e93f7393Sniklas   s = p;
434e93f7393Sniklas   while (*p && (*p != ' ' && *p != '\t'))
435e93f7393Sniklas     {
436e93f7393Sniklas       l++;
437e93f7393Sniklas       p++;
438e93f7393Sniklas     }
439e93f7393Sniklas   r = xmalloc (l + 1);
440e93f7393Sniklas   memcpy (r, s, l);
441e93f7393Sniklas   r[l] = 0;
442e93f7393Sniklas   *ptr = p;
443e93f7393Sniklas   return r;
444e93f7393Sniklas }
445e93f7393Sniklas 
446e93f7393Sniklas static void
e7000_login_command(char * args,int from_tty)447b725ae77Skettenis e7000_login_command (char *args, int from_tty)
448e93f7393Sniklas {
449e93f7393Sniklas   if (args)
450e93f7393Sniklas     {
451e93f7393Sniklas       machine = next (&args);
452e93f7393Sniklas       user = next (&args);
453e93f7393Sniklas       passwd = next (&args);
454e93f7393Sniklas       dir = next (&args);
455e93f7393Sniklas       if (from_tty)
456e93f7393Sniklas 	{
457b725ae77Skettenis 	  printf_unfiltered ("Set info to %s %s %s %s\n", machine, user, passwd, dir);
458e93f7393Sniklas 	}
459e93f7393Sniklas     }
460e93f7393Sniklas   else
461e93f7393Sniklas     {
462e93f7393Sniklas       error ("Syntax is ftplogin <machine> <user> <passwd> <directory>");
463e93f7393Sniklas     }
464e93f7393Sniklas }
465e93f7393Sniklas 
466e93f7393Sniklas /* Start an ftp transfer from the E7000 to a host */
467e93f7393Sniklas 
468e93f7393Sniklas static void
e7000_ftp_command(char * args,int from_tty)469b725ae77Skettenis e7000_ftp_command (char *args, int from_tty)
470e93f7393Sniklas {
471e93f7393Sniklas   /* FIXME: arbitrary limit on machine names and such.  */
472e93f7393Sniklas   char buf[200];
473e93f7393Sniklas 
474e93f7393Sniklas   int oldtimeout = timeout;
475e93f7393Sniklas   timeout = remote_timeout;
476e93f7393Sniklas 
477e93f7393Sniklas   sprintf (buf, "ftp %s\r", machine);
478e93f7393Sniklas   puts_e7000debug (buf);
479e93f7393Sniklas   expect (" Username : ");
480e93f7393Sniklas   sprintf (buf, "%s\r", user);
481e93f7393Sniklas   puts_e7000debug (buf);
482e93f7393Sniklas   expect (" Password : ");
483e93f7393Sniklas   write_e7000 (passwd);
484e93f7393Sniklas   write_e7000 ("\r");
485e93f7393Sniklas   expect ("success\r");
486e93f7393Sniklas   expect ("FTP>");
487e93f7393Sniklas   sprintf (buf, "cd %s\r", dir);
488e93f7393Sniklas   puts_e7000debug (buf);
489e93f7393Sniklas   expect ("FTP>");
490e93f7393Sniklas   sprintf (buf, "ll 0;s:%s\r", args);
491e93f7393Sniklas   puts_e7000debug (buf);
492e93f7393Sniklas   expect ("FTP>");
493e93f7393Sniklas   puts_e7000debug ("bye\r");
494e93f7393Sniklas   expect (":");
495e93f7393Sniklas   timeout = oldtimeout;
496e93f7393Sniklas }
497e93f7393Sniklas 
498e93f7393Sniklas static int
e7000_parse_device(char * args,char * dev_name,int baudrate)499b725ae77Skettenis e7000_parse_device (char *args, char *dev_name, int baudrate)
500e93f7393Sniklas {
501e93f7393Sniklas   char junk[128];
502e93f7393Sniklas   int n = 0;
503e93f7393Sniklas   if (args && strcasecmp (args, "pc") == 0)
504e93f7393Sniklas     {
505e93f7393Sniklas       strcpy (dev_name, args);
506e93f7393Sniklas       using_pc = 1;
507e93f7393Sniklas     }
508e93f7393Sniklas   else
509e93f7393Sniklas     {
510e93f7393Sniklas       /* FIXME! temp hack to allow use with port master -
511e93f7393Sniklas          target tcp_remote <device> */
512b725ae77Skettenis       if (args && strncmp (args, "tcp", 10) == 0)
513e93f7393Sniklas 	{
514e93f7393Sniklas 	  char com_type[128];
515e93f7393Sniklas 	  n = sscanf (args, " %s %s %d %s", com_type, dev_name, &baudrate, junk);
516e93f7393Sniklas 	  using_tcp_remote = 1;
517e93f7393Sniklas 	  n--;
518e93f7393Sniklas 	}
519e93f7393Sniklas       else if (args)
520e93f7393Sniklas 	{
521e93f7393Sniklas 	  n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk);
522e93f7393Sniklas 	}
523e93f7393Sniklas 
524e93f7393Sniklas       if (n != 1 && n != 2)
525e93f7393Sniklas 	{
526e93f7393Sniklas 	  error ("Bad arguments.  Usage:\ttarget e7000 <device> <speed>\n\
527e93f7393Sniklas or \t\ttarget e7000 <host>[:<port>]\n\
528e93f7393Sniklas or \t\ttarget e7000 tcp_remote <host>[:<port>]\n\
529e93f7393Sniklas or \t\ttarget e7000 pc\n");
530e93f7393Sniklas 	}
531e93f7393Sniklas 
532b725ae77Skettenis #if !defined(__GO32__) && !defined(_WIN32) && !defined(__CYGWIN__)
533e93f7393Sniklas       /* FIXME!  test for ':' is ambiguous */
534e93f7393Sniklas       if (n == 1 && strchr (dev_name, ':') == 0)
535e93f7393Sniklas 	{
536e93f7393Sniklas 	  /* Default to normal telnet port */
537e93f7393Sniklas 	  /* serial_open will use this to determine tcp communication */
538e93f7393Sniklas 	  strcat (dev_name, ":23");
539e93f7393Sniklas 	}
540e93f7393Sniklas #endif
541e93f7393Sniklas       if (!using_tcp_remote && strchr (dev_name, ':'))
542e93f7393Sniklas 	using_tcp = 1;
543e93f7393Sniklas     }
544e93f7393Sniklas 
545e93f7393Sniklas   return n;
546e93f7393Sniklas }
547e93f7393Sniklas 
548b725ae77Skettenis /* Stub for catch_errors.  */
549b725ae77Skettenis 
550b725ae77Skettenis static int
e7000_start_remote(void * dummy)551b725ae77Skettenis e7000_start_remote (void *dummy)
552e93f7393Sniklas {
553e93f7393Sniklas   int loop;
554e93f7393Sniklas   int sync;
555b725ae77Skettenis   int try;
556b725ae77Skettenis   int quit_trying;
557e93f7393Sniklas 
558b725ae77Skettenis   immediate_quit++;		/* Allow user to interrupt it */
559e93f7393Sniklas 
560e93f7393Sniklas   /* Hello?  Are you there?  */
561e93f7393Sniklas   sync = 0;
562e93f7393Sniklas   loop = 0;
563b725ae77Skettenis   try = 0;
564b725ae77Skettenis   quit_trying = 20;
565e93f7393Sniklas   putchar_e7000 (CTRLC);
566b725ae77Skettenis   while (!sync && ++try <= quit_trying)
567e93f7393Sniklas     {
568e93f7393Sniklas       int c;
569e93f7393Sniklas 
570e93f7393Sniklas       printf_unfiltered ("[waiting for e7000...]\n");
571e93f7393Sniklas 
572e93f7393Sniklas       write_e7000 ("\r");
573b725ae77Skettenis       c = readchar (1);
574b725ae77Skettenis 
575b725ae77Skettenis       /* FIXME!  this didn't seem right->  while (c != SERIAL_TIMEOUT)
576b725ae77Skettenis        * we get stuck in this loop ...
577b725ae77Skettenis        * We may never timeout, and never sync up :-(
578b725ae77Skettenis        */
579b725ae77Skettenis       while (!sync && c != -1)
580e93f7393Sniklas 	{
581e93f7393Sniklas 	  /* Dont echo cr's */
582b725ae77Skettenis 	  if (c != '\r')
583e93f7393Sniklas 	    {
584b725ae77Skettenis 	      putchar_unfiltered (c);
585b725ae77Skettenis 	      gdb_flush (gdb_stdout);
586e93f7393Sniklas 	    }
587b725ae77Skettenis 	  /* Shouldn't we either break here, or check for sync in inner loop? */
588e93f7393Sniklas 	  if (c == ':')
589e93f7393Sniklas 	    sync = 1;
590e93f7393Sniklas 
591e93f7393Sniklas 	  if (loop++ == 20)
592e93f7393Sniklas 	    {
593e93f7393Sniklas 	      putchar_e7000 (CTRLC);
594e93f7393Sniklas 	      loop = 0;
595e93f7393Sniklas 	    }
596e93f7393Sniklas 
597e93f7393Sniklas 	  QUIT;
598e93f7393Sniklas 
599e93f7393Sniklas 	  if (quit_flag)
600e93f7393Sniklas 	    {
601e93f7393Sniklas 	      putchar_e7000 (CTRLC);
602b725ae77Skettenis 	      /* Was-> quit_flag = 0; */
603b725ae77Skettenis 	      c = -1;
604b725ae77Skettenis 	      quit_trying = try + 1;	/* we don't want to try anymore */
605e93f7393Sniklas 	    }
606b725ae77Skettenis 	  else
607b725ae77Skettenis 	    {
608b725ae77Skettenis 	      c = readchar (1);
609e93f7393Sniklas 	    }
610e93f7393Sniklas 	}
611b725ae77Skettenis     }
612b725ae77Skettenis 
613b725ae77Skettenis   if (!sync)
614b725ae77Skettenis     {
615b725ae77Skettenis       fprintf_unfiltered (gdb_stderr, "Giving up after %d tries...\n", try);
616b725ae77Skettenis       error ("Unable to synchronize with target.\n");
617b725ae77Skettenis     }
618b725ae77Skettenis 
619e93f7393Sniklas   puts_e7000debug ("\r");
620b725ae77Skettenis   expect_prompt ();
621b725ae77Skettenis   puts_e7000debug ("b -\r");	/* Clear breakpoints */
622e93f7393Sniklas   expect_prompt ();
623e93f7393Sniklas 
624b725ae77Skettenis   immediate_quit--;
625e93f7393Sniklas 
626b725ae77Skettenis /* This is really the job of start_remote however, that makes an assumption
627b725ae77Skettenis    that the target is about to print out a status message of some sort.  That
628b725ae77Skettenis    doesn't happen here. */
629e93f7393Sniklas 
630b725ae77Skettenis   flush_cached_frames ();
631b725ae77Skettenis   registers_changed ();
632b725ae77Skettenis   stop_pc = read_pc ();
633*63addd46Skettenis   print_stack_frame (get_selected_frame (), 0, SRC_AND_LOC);
634b725ae77Skettenis 
635b725ae77Skettenis   return 1;
636b725ae77Skettenis }
637b725ae77Skettenis 
638b725ae77Skettenis static void
e7000_open(char * args,int from_tty)639b725ae77Skettenis e7000_open (char *args, int from_tty)
640b725ae77Skettenis {
641b725ae77Skettenis   int n;
642b725ae77Skettenis 
643b725ae77Skettenis   target_preopen (from_tty);
644b725ae77Skettenis 
645b725ae77Skettenis   n = e7000_parse_device (args, dev_name, baudrate);
646b725ae77Skettenis 
647b725ae77Skettenis   push_target (&e7000_ops);
648b725ae77Skettenis 
649b725ae77Skettenis   e7000_desc = serial_open (dev_name);
650b725ae77Skettenis 
651b725ae77Skettenis   if (!e7000_desc)
652b725ae77Skettenis     perror_with_name (dev_name);
653b725ae77Skettenis 
654b725ae77Skettenis   if (serial_setbaudrate (e7000_desc, baudrate))
655b725ae77Skettenis     {
656b725ae77Skettenis       serial_close (e7000_desc);
657b725ae77Skettenis       perror_with_name (dev_name);
658b725ae77Skettenis     }
659b725ae77Skettenis   serial_raw (e7000_desc);
660b725ae77Skettenis 
661b725ae77Skettenis   /* Start the remote connection; if error (0), discard this target.
662b725ae77Skettenis      In particular, if the user quits, be sure to discard it
663b725ae77Skettenis      (we'd be in an inconsistent state otherwise).  */
664b725ae77Skettenis   if (!catch_errors (e7000_start_remote, (char *) 0,
665b725ae77Skettenis        "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
666e93f7393Sniklas     if (from_tty)
667e93f7393Sniklas       printf_filtered ("Remote target %s connected to %s\n", target_shortname,
668e93f7393Sniklas 		       dev_name);
669e93f7393Sniklas }
670e93f7393Sniklas 
671e93f7393Sniklas /* Close out all files and local state before this target loses control. */
672e93f7393Sniklas 
673e93f7393Sniklas static void
e7000_close(int quitting)674b725ae77Skettenis e7000_close (int quitting)
675e93f7393Sniklas {
676e93f7393Sniklas   if (e7000_desc)
677e93f7393Sniklas     {
678b725ae77Skettenis       serial_close (e7000_desc);
679e93f7393Sniklas       e7000_desc = 0;
680e93f7393Sniklas     }
681e93f7393Sniklas }
682e93f7393Sniklas 
683e93f7393Sniklas /* Terminate the open connection to the remote debugger.  Use this
684e93f7393Sniklas    when you want to detach and do something else with your gdb.  */
685e93f7393Sniklas 
686e93f7393Sniklas static void
e7000_detach(char * arg,int from_tty)687b725ae77Skettenis e7000_detach (char *arg, int from_tty)
688e93f7393Sniklas {
689e93f7393Sniklas   pop_target ();		/* calls e7000_close to do the real work */
690e93f7393Sniklas   if (from_tty)
691b725ae77Skettenis     printf_unfiltered ("Ending remote %s debugging\n", target_shortname);
692e93f7393Sniklas }
693e93f7393Sniklas 
694e93f7393Sniklas /* Tell the remote machine to resume.  */
695e93f7393Sniklas 
696e93f7393Sniklas static void
e7000_resume(ptid_t ptid,int step,enum target_signal sigal)697b725ae77Skettenis e7000_resume (ptid_t ptid, int step, enum target_signal sigal)
698e93f7393Sniklas {
699e93f7393Sniklas   if (step)
700e93f7393Sniklas     puts_e7000debug ("S\r");
701e93f7393Sniklas   else
702e93f7393Sniklas     puts_e7000debug ("G\r");
703e93f7393Sniklas }
704e93f7393Sniklas 
705e93f7393Sniklas /* Read the remote registers into the block REGS.
706e93f7393Sniklas 
707e93f7393Sniklas    For the H8/300 a register dump looks like:
708e93f7393Sniklas 
709e93f7393Sniklas    PC=00021A  CCR=80:I*******
710e93f7393Sniklas    ER0 - ER3  0000000A 0000002E 0000002E 00000000
711e93f7393Sniklas    ER4 - ER7  00000000 00000000 00000000 00FFEFF6
712e93f7393Sniklas    000218           MOV.B     R1L,R2L
713e93f7393Sniklas    STEP NORMAL END or
714e93f7393Sniklas    BREAK POINT
715e93f7393Sniklas  */
716e93f7393Sniklas 
717b725ae77Skettenis char *want_h8300h = "PC=%p CCR=%c\n\
718e93f7393Sniklas  ER0 - ER3  %0 %1 %2 %3\n\
719e93f7393Sniklas  ER4 - ER7  %4 %5 %6 %7\n";
720e93f7393Sniklas 
721b725ae77Skettenis char *want_nopc_h8300h = "%p CCR=%c\n\
722e93f7393Sniklas  ER0 - ER3  %0 %1 %2 %3\n\
723e93f7393Sniklas  ER4 - ER7  %4 %5 %6 %7";
724e93f7393Sniklas 
725b725ae77Skettenis char *want_h8300s = "PC=%p CCR=%c\n\
726b725ae77Skettenis  MACH=\n\
727b725ae77Skettenis  ER0 - ER3  %0 %1 %2 %3\n\
728b725ae77Skettenis  ER4 - ER7  %4 %5 %6 %7\n";
729e93f7393Sniklas 
730b725ae77Skettenis char *want_nopc_h8300s = "%p CCR=%c EXR=%9\n\
731b725ae77Skettenis  ER0 - ER3  %0 %1 %2 %3\n\
732b725ae77Skettenis  ER4 - ER7  %4 %5 %6 %7";
733e93f7393Sniklas 
734b725ae77Skettenis char *want_sh = "PC=%16 SR=%22\n\
735e93f7393Sniklas PR=%17 GBR=%18 VBR=%19\n\
736e93f7393Sniklas MACH=%20 MACL=%21\n\
737e93f7393Sniklas R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
738e93f7393Sniklas R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n";
739e93f7393Sniklas 
740b725ae77Skettenis char *want_nopc_sh = "%16 SR=%22\n\
741e93f7393Sniklas  PR=%17 GBR=%18 VBR=%19\n\
742e93f7393Sniklas  MACH=%20 MACL=%21\n\
743e93f7393Sniklas  R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
744e93f7393Sniklas  R8-15 %8 %9 %10 %11 %12 %13 %14 %15";
745e93f7393Sniklas 
746e93f7393Sniklas char *want_sh3 = "PC=%16 SR=%22\n\
747e93f7393Sniklas PR=%17 GBR=%18 VBR=%19\n\
748e93f7393Sniklas MACH=%20 MACL=%21 SSR=%23 SPC=%24\n\
749e93f7393Sniklas R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
750e93f7393Sniklas R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
751e93f7393Sniklas R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
752e93f7393Sniklas R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
753e93f7393Sniklas R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
754e93f7393Sniklas R4_BANK1-R7_BANK1 %37 %38 %39 %40";
755e93f7393Sniklas 
756b725ae77Skettenis char *want_nopc_sh3 = "%16 SR=%22\n\
757e93f7393Sniklas  PR=%17 GBR=%18 VBR=%19\n\
758e93f7393Sniklas  MACH=%20 MACL=%21 SSR=%22 SPC=%23\n\
759e93f7393Sniklas  R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
760e93f7393Sniklas  R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
761e93f7393Sniklas  R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
762e93f7393Sniklas  R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
763e93f7393Sniklas  R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
764e93f7393Sniklas  R4_BANK1-R7_BANK1 %37 %38 %39 %40";
765e93f7393Sniklas 
766e93f7393Sniklas static int
gch(void)767b725ae77Skettenis gch (void)
768e93f7393Sniklas {
769b725ae77Skettenis   return readchar (timeout);
770e93f7393Sniklas }
771e93f7393Sniklas 
772e93f7393Sniklas static unsigned int
gbyte(void)773b725ae77Skettenis gbyte (void)
774e93f7393Sniklas {
775e93f7393Sniklas   int high = convert_hex_digit (gch ());
776e93f7393Sniklas   int low = convert_hex_digit (gch ());
777e93f7393Sniklas 
778e93f7393Sniklas   return (high << 4) + low;
779e93f7393Sniklas }
780e93f7393Sniklas 
781b725ae77Skettenis static void
fetch_regs_from_dump(int (* nextchar)(),char * want)782b725ae77Skettenis fetch_regs_from_dump (int (*nextchar) (), char *want)
783e93f7393Sniklas {
784e93f7393Sniklas   int regno;
785b725ae77Skettenis   char buf[MAX_REGISTER_SIZE];
786e93f7393Sniklas 
787e93f7393Sniklas   int thischar = nextchar ();
788e93f7393Sniklas 
789b725ae77Skettenis   if (want == NULL)
790b725ae77Skettenis     internal_error (__FILE__, __LINE__, "Register set not selected.");
791b725ae77Skettenis 
792e93f7393Sniklas   while (*want)
793e93f7393Sniklas     {
794e93f7393Sniklas       switch (*want)
795e93f7393Sniklas 	{
796e93f7393Sniklas 	case '\n':
797e93f7393Sniklas 	  /* Skip to end of line and then eat all new line type stuff */
798e93f7393Sniklas 	  while (thischar != '\n' && thischar != '\r')
799e93f7393Sniklas 	    thischar = nextchar ();
800e93f7393Sniklas 	  while (thischar == '\n' || thischar == '\r')
801e93f7393Sniklas 	    thischar = nextchar ();
802e93f7393Sniklas 	  want++;
803e93f7393Sniklas 	  break;
804e93f7393Sniklas 
805e93f7393Sniklas 	case ' ':
806e93f7393Sniklas 	  while (thischar == ' '
807e93f7393Sniklas 		 || thischar == '\t'
808e93f7393Sniklas 		 || thischar == '\r'
809e93f7393Sniklas 		 || thischar == '\n')
810e93f7393Sniklas 	    thischar = nextchar ();
811e93f7393Sniklas 	  want++;
812e93f7393Sniklas 	  break;
813e93f7393Sniklas 
814e93f7393Sniklas 	default:
815e93f7393Sniklas 	  if (*want == thischar)
816e93f7393Sniklas 	    {
817e93f7393Sniklas 	      want++;
818e93f7393Sniklas 	      if (*want)
819e93f7393Sniklas 		thischar = nextchar ();
820e93f7393Sniklas 
821e93f7393Sniklas 	    }
822e93f7393Sniklas 	  else if (thischar == ' ' || thischar == '\n' || thischar == '\r')
823e93f7393Sniklas 	    {
824e93f7393Sniklas 	      thischar = nextchar ();
825e93f7393Sniklas 	    }
826b725ae77Skettenis 	  else
827b725ae77Skettenis 	    {
828e93f7393Sniklas 	      error ("out of sync in fetch registers wanted <%s>, got <%c 0x%x>",
829e93f7393Sniklas 		     want, thischar, thischar);
830e93f7393Sniklas 	    }
831e93f7393Sniklas 
832e93f7393Sniklas 	  break;
833e93f7393Sniklas 	case '%':
834e93f7393Sniklas 	  /* Got a register command */
835e93f7393Sniklas 	  want++;
836e93f7393Sniklas 	  switch (*want)
837e93f7393Sniklas 	    {
838e93f7393Sniklas #ifdef PC_REGNUM
839e93f7393Sniklas 	    case 'p':
840e93f7393Sniklas 	      regno = PC_REGNUM;
841e93f7393Sniklas 	      want++;
842e93f7393Sniklas 	      break;
843e93f7393Sniklas #endif
844e93f7393Sniklas #ifdef CCR_REGNUM
845e93f7393Sniklas 	    case 'c':
846e93f7393Sniklas 	      regno = CCR_REGNUM;
847e93f7393Sniklas 	      want++;
848e93f7393Sniklas 	      break;
849e93f7393Sniklas #endif
850e93f7393Sniklas #ifdef SP_REGNUM
851e93f7393Sniklas 	    case 's':
852e93f7393Sniklas 	      regno = SP_REGNUM;
853e93f7393Sniklas 	      want++;
854e93f7393Sniklas 	      break;
855e93f7393Sniklas #endif
856b725ae77Skettenis #ifdef DEPRECATED_FP_REGNUM
857e93f7393Sniklas 	    case 'f':
858b725ae77Skettenis 	      regno = DEPRECATED_FP_REGNUM;
859e93f7393Sniklas 	      want++;
860e93f7393Sniklas 	      break;
861e93f7393Sniklas #endif
862e93f7393Sniklas 
863e93f7393Sniklas 	    default:
864e93f7393Sniklas 	      if (isdigit (want[0]))
865e93f7393Sniklas 		{
866e93f7393Sniklas 		  if (isdigit (want[1]))
867e93f7393Sniklas 		    {
868e93f7393Sniklas 		      regno = (want[0] - '0') * 10 + want[1] - '0';
869e93f7393Sniklas 		      want += 2;
870e93f7393Sniklas 		    }
871e93f7393Sniklas 		  else
872e93f7393Sniklas 		    {
873e93f7393Sniklas 		      regno = want[0] - '0';
874e93f7393Sniklas 		      want++;
875e93f7393Sniklas 		    }
876e93f7393Sniklas 		}
877e93f7393Sniklas 
878e93f7393Sniklas 	      else
879b725ae77Skettenis 		internal_error (__FILE__, __LINE__, "failed internal consistency check");
880e93f7393Sniklas 	    }
881e93f7393Sniklas 	  store_signed_integer (buf,
882*63addd46Skettenis 				register_size (current_gdbarch, regno),
883b725ae77Skettenis 				(LONGEST) get_hex (&thischar));
884*63addd46Skettenis 	  regcache_raw_supply (current_regcache, regno, buf);
885e93f7393Sniklas 	  break;
886e93f7393Sniklas 	}
887e93f7393Sniklas     }
888e93f7393Sniklas }
889e93f7393Sniklas 
890e93f7393Sniklas static void
e7000_fetch_registers(void)891b725ae77Skettenis e7000_fetch_registers (void)
892e93f7393Sniklas {
893e93f7393Sniklas   int regno;
894b725ae77Skettenis   char *wanted = NULL;
895e93f7393Sniklas 
896e93f7393Sniklas   puts_e7000debug ("R\r");
897e93f7393Sniklas 
898b725ae77Skettenis   if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
899b725ae77Skettenis     {
900b725ae77Skettenis       wanted = want_sh;
901b725ae77Skettenis       switch (TARGET_ARCHITECTURE->mach)
902b725ae77Skettenis 	{
903b725ae77Skettenis 	case bfd_mach_sh3:
904b725ae77Skettenis 	case bfd_mach_sh3e:
905b725ae77Skettenis 	case bfd_mach_sh4:
906b725ae77Skettenis 	  wanted = want_sh3;
907b725ae77Skettenis 	}
908b725ae77Skettenis     }
909b725ae77Skettenis   if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300)
910b725ae77Skettenis     {
911b725ae77Skettenis       wanted = want_h8300h;
912b725ae77Skettenis       switch (TARGET_ARCHITECTURE->mach)
913b725ae77Skettenis 	{
914b725ae77Skettenis 	case bfd_mach_h8300s:
915b725ae77Skettenis 	case bfd_mach_h8300sn:
916b725ae77Skettenis 	case bfd_mach_h8300sx:
917b725ae77Skettenis 	case bfd_mach_h8300sxn:
918b725ae77Skettenis 	  wanted = want_h8300s;
919b725ae77Skettenis 	}
920b725ae77Skettenis     }
921e93f7393Sniklas 
922b725ae77Skettenis   fetch_regs_from_dump (gch, wanted);
923e93f7393Sniklas 
924e93f7393Sniklas   /* And supply the extra ones the simulator uses */
925e93f7393Sniklas   for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
926e93f7393Sniklas     {
927e93f7393Sniklas       int buf = 0;
928e93f7393Sniklas 
929*63addd46Skettenis       regcache_raw_supply (current_regcache, regno, (char *) (&buf));
930e93f7393Sniklas     }
931e93f7393Sniklas }
932e93f7393Sniklas 
933e93f7393Sniklas /* Fetch register REGNO, or all registers if REGNO is -1.  Returns
934e93f7393Sniklas    errno value.  */
935e93f7393Sniklas 
936e93f7393Sniklas static void
e7000_fetch_register(int regno)937b725ae77Skettenis e7000_fetch_register (int regno)
938e93f7393Sniklas {
939e93f7393Sniklas   e7000_fetch_registers ();
940e93f7393Sniklas }
941e93f7393Sniklas 
942e93f7393Sniklas /* Store the remote registers from the contents of the block REGS.  */
943e93f7393Sniklas 
944e93f7393Sniklas static void
e7000_store_registers(void)945b725ae77Skettenis e7000_store_registers (void)
946e93f7393Sniklas {
947e93f7393Sniklas   int regno;
948e93f7393Sniklas 
949e93f7393Sniklas   for (regno = 0; regno < NUM_REALREGS; regno++)
950e93f7393Sniklas     e7000_store_register (regno);
951e93f7393Sniklas 
952e93f7393Sniklas   registers_changed ();
953e93f7393Sniklas }
954e93f7393Sniklas 
955e93f7393Sniklas /* Store register REGNO, or all if REGNO == 0.  Return errno value.  */
956e93f7393Sniklas 
957e93f7393Sniklas static void
e7000_store_register(int regno)958b725ae77Skettenis e7000_store_register (int regno)
959e93f7393Sniklas {
960e93f7393Sniklas   char buf[200];
961e93f7393Sniklas 
962e93f7393Sniklas   if (regno == -1)
963e93f7393Sniklas     {
964e93f7393Sniklas       e7000_store_registers ();
965e93f7393Sniklas       return;
966e93f7393Sniklas     }
967e93f7393Sniklas 
968b725ae77Skettenis   if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300)
969b725ae77Skettenis     {
970e93f7393Sniklas       if (regno <= 7)
971e93f7393Sniklas 	{
972b725ae77Skettenis 	  sprintf (buf, ".ER%d %s\r", regno, phex_nz (read_register (regno), 0));
973e93f7393Sniklas 	  puts_e7000debug (buf);
974e93f7393Sniklas 	}
975e93f7393Sniklas       else if (regno == PC_REGNUM)
976e93f7393Sniklas 	{
977b725ae77Skettenis 	  sprintf (buf, ".PC %s\r", phex_nz (read_register (regno), 0));
978e93f7393Sniklas 	  puts_e7000debug (buf);
979e93f7393Sniklas 	}
980b725ae77Skettenis #ifdef CCR_REGNUM
981e93f7393Sniklas       else if (regno == CCR_REGNUM)
982e93f7393Sniklas 	{
983b725ae77Skettenis 	  sprintf (buf, ".CCR %s\r", phex_nz (read_register (regno), 0));
984e93f7393Sniklas 	  puts_e7000debug (buf);
985e93f7393Sniklas 	}
986b725ae77Skettenis #endif
987b725ae77Skettenis     }
988e93f7393Sniklas 
989b725ae77Skettenis   else if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
990e93f7393Sniklas     {
991b725ae77Skettenis       if (regno == PC_REGNUM)
992b725ae77Skettenis 	{
993b725ae77Skettenis 	  sprintf (buf, ".PC %s\r", phex_nz (read_register (regno), 0));
994e93f7393Sniklas 	  puts_e7000debug (buf);
995e93f7393Sniklas 	}
996e93f7393Sniklas 
997b725ae77Skettenis       else if (regno == SR_REGNUM)
998b725ae77Skettenis 	{
999b725ae77Skettenis 	  sprintf (buf, ".SR %s\r", phex_nz (read_register (regno), 0));
1000b725ae77Skettenis 	  puts_e7000debug (buf);
1001b725ae77Skettenis 	}
1002b725ae77Skettenis 
1003b725ae77Skettenis       else if (regno ==  PR_REGNUM)
1004b725ae77Skettenis 	{
1005b725ae77Skettenis 	  sprintf (buf, ".PR %s\r", phex_nz (read_register (regno), 0));
1006b725ae77Skettenis 	  puts_e7000debug (buf);
1007b725ae77Skettenis 	}
1008b725ae77Skettenis 
1009b725ae77Skettenis       else if (regno == GBR_REGNUM)
1010b725ae77Skettenis 	{
1011b725ae77Skettenis 	  sprintf (buf, ".GBR %s\r", phex_nz (read_register (regno), 0));
1012b725ae77Skettenis 	  puts_e7000debug (buf);
1013b725ae77Skettenis 	}
1014b725ae77Skettenis 
1015b725ae77Skettenis       else if (regno == VBR_REGNUM)
1016b725ae77Skettenis 	{
1017b725ae77Skettenis 	  sprintf (buf, ".VBR %s\r", phex_nz (read_register (regno), 0));
1018b725ae77Skettenis 	  puts_e7000debug (buf);
1019b725ae77Skettenis 	}
1020b725ae77Skettenis 
1021b725ae77Skettenis       else if (regno == MACH_REGNUM)
1022b725ae77Skettenis 	{
1023b725ae77Skettenis 	  sprintf (buf, ".MACH %s\r", phex_nz (read_register (regno), 0));
1024b725ae77Skettenis 	  puts_e7000debug (buf);
1025b725ae77Skettenis 	}
1026b725ae77Skettenis 
1027b725ae77Skettenis       else if (regno == MACL_REGNUM)
1028b725ae77Skettenis 	{
1029b725ae77Skettenis 	  sprintf (buf, ".MACL %s\r", phex_nz (read_register (regno), 0));
1030b725ae77Skettenis 	  puts_e7000debug (buf);
1031b725ae77Skettenis 	}
1032b725ae77Skettenis       else
1033b725ae77Skettenis 	{
1034b725ae77Skettenis 	  sprintf (buf, ".R%d %s\r", regno, phex_nz (read_register (regno), 0));
1035b725ae77Skettenis 	  puts_e7000debug (buf);
1036b725ae77Skettenis 	}
1037b725ae77Skettenis     }
1038e93f7393Sniklas 
1039e93f7393Sniklas   expect_prompt ();
1040e93f7393Sniklas }
1041e93f7393Sniklas 
1042e93f7393Sniklas /* Get ready to modify the registers array.  On machines which store
1043e93f7393Sniklas    individual registers, this doesn't need to do anything.  On machines
1044e93f7393Sniklas    which store all the registers in one fell swoop, this makes sure
1045e93f7393Sniklas    that registers contains all the registers from the program being
1046e93f7393Sniklas    debugged.  */
1047e93f7393Sniklas 
1048e93f7393Sniklas static void
e7000_prepare_to_store(void)1049b725ae77Skettenis e7000_prepare_to_store (void)
1050e93f7393Sniklas {
1051e93f7393Sniklas   /* Do nothing, since we can store individual regs */
1052e93f7393Sniklas }
1053e93f7393Sniklas 
1054e93f7393Sniklas static void
e7000_files_info(struct target_ops * ops)1055b725ae77Skettenis e7000_files_info (struct target_ops *ops)
1056e93f7393Sniklas {
1057b725ae77Skettenis   printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baudrate);
1058e93f7393Sniklas }
1059e93f7393Sniklas 
1060e93f7393Sniklas static int
stickbyte(char * where,unsigned int what)1061b725ae77Skettenis stickbyte (char *where, unsigned int what)
1062e93f7393Sniklas {
1063e93f7393Sniklas   static CONST char digs[] = "0123456789ABCDEF";
1064e93f7393Sniklas 
1065e93f7393Sniklas   where[0] = digs[(what >> 4) & 0xf];
1066e93f7393Sniklas   where[1] = digs[(what & 0xf) & 0xf];
1067e93f7393Sniklas 
1068e93f7393Sniklas   return what;
1069e93f7393Sniklas }
1070e93f7393Sniklas 
1071e93f7393Sniklas /* Write a small ammount of memory. */
1072e93f7393Sniklas 
1073e93f7393Sniklas static int
write_small(CORE_ADDR memaddr,unsigned char * myaddr,int len)1074b725ae77Skettenis write_small (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1075e93f7393Sniklas {
1076e93f7393Sniklas   int i;
1077e93f7393Sniklas   char buf[200];
1078e93f7393Sniklas 
1079e93f7393Sniklas   for (i = 0; i < len; i++)
1080e93f7393Sniklas     {
1081e93f7393Sniklas       if (((memaddr + i) & 3) == 0 && (i + 3 < len))
1082e93f7393Sniklas 	{
1083e93f7393Sniklas 	  /* Can be done with a long word */
1084b725ae77Skettenis 	  sprintf (buf, "m %s %x%02x%02x%02x;l\r",
1085b725ae77Skettenis 		   paddr_nz (memaddr + i),
1086e93f7393Sniklas 		   myaddr[i], myaddr[i + 1], myaddr[i + 2], myaddr[i + 3]);
1087e93f7393Sniklas 	  puts_e7000debug (buf);
1088e93f7393Sniklas 	  i += 3;
1089e93f7393Sniklas 	}
1090e93f7393Sniklas       else
1091e93f7393Sniklas 	{
1092b725ae77Skettenis 	  sprintf (buf, "m %s %x\r", paddr_nz (memaddr + i), myaddr[i]);
1093e93f7393Sniklas 	  puts_e7000debug (buf);
1094e93f7393Sniklas 	}
1095e93f7393Sniklas     }
1096e93f7393Sniklas 
1097e93f7393Sniklas   expect_prompt ();
1098e93f7393Sniklas 
1099e93f7393Sniklas   return len;
1100e93f7393Sniklas }
1101e93f7393Sniklas 
1102e93f7393Sniklas /* Write a large ammount of memory, this only works with the serial
1103e93f7393Sniklas    mode enabled.  Command is sent as
1104e93f7393Sniklas 
1105e93f7393Sniklas    il ;s:s\r     ->
1106e93f7393Sniklas    <- il ;s:s\r
1107e93f7393Sniklas    <-   ENQ
1108e93f7393Sniklas    ACK          ->
1109e93f7393Sniklas    <- LO s\r
1110e93f7393Sniklas    Srecords...
1111e93f7393Sniklas    ^Z           ->
1112e93f7393Sniklas    <-   ENQ
1113e93f7393Sniklas    ACK          ->
1114e93f7393Sniklas    <-   :
1115e93f7393Sniklas  */
1116e93f7393Sniklas 
1117e93f7393Sniklas static int
write_large(CORE_ADDR memaddr,unsigned char * myaddr,int len)1118b725ae77Skettenis write_large (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1119e93f7393Sniklas {
1120e93f7393Sniklas   int i;
1121e93f7393Sniklas #define maxstride  128
1122e93f7393Sniklas   int stride;
1123e93f7393Sniklas 
1124e93f7393Sniklas   puts_e7000debug ("IL ;S:FK\r");
1125e93f7393Sniklas   expect (ENQSTRING);
1126e93f7393Sniklas   putchar_e7000 (ACK);
1127e93f7393Sniklas   expect ("LO FK\r");
1128e93f7393Sniklas 
1129e93f7393Sniklas   for (i = 0; i < len; i += stride)
1130e93f7393Sniklas     {
1131e93f7393Sniklas       char compose[maxstride * 2 + 50];
1132e93f7393Sniklas       int address = i + memaddr;
1133e93f7393Sniklas       int j;
1134e93f7393Sniklas       int check_sum;
1135e93f7393Sniklas       int where = 0;
1136e93f7393Sniklas       int alen;
1137e93f7393Sniklas 
1138e93f7393Sniklas       stride = len - i;
1139e93f7393Sniklas       if (stride > maxstride)
1140e93f7393Sniklas 	stride = maxstride;
1141e93f7393Sniklas 
1142e93f7393Sniklas       compose[where++] = 'S';
1143e93f7393Sniklas       check_sum = 0;
1144e93f7393Sniklas       if (address >= 0xffffff)
1145e93f7393Sniklas 	alen = 4;
1146e93f7393Sniklas       else if (address >= 0xffff)
1147e93f7393Sniklas 	alen = 3;
1148e93f7393Sniklas       else
1149e93f7393Sniklas 	alen = 2;
1150e93f7393Sniklas       /* Insert type. */
1151e93f7393Sniklas       compose[where++] = alen - 1 + '0';
1152e93f7393Sniklas       /* Insert length. */
1153e93f7393Sniklas       check_sum += stickbyte (compose + where, alen + stride + 1);
1154e93f7393Sniklas       where += 2;
1155e93f7393Sniklas       while (alen > 0)
1156e93f7393Sniklas 	{
1157e93f7393Sniklas 	  alen--;
1158e93f7393Sniklas 	  check_sum += stickbyte (compose + where, address >> (8 * (alen)));
1159e93f7393Sniklas 	  where += 2;
1160e93f7393Sniklas 	}
1161e93f7393Sniklas 
1162e93f7393Sniklas       for (j = 0; j < stride; j++)
1163e93f7393Sniklas 	{
1164e93f7393Sniklas 	  check_sum += stickbyte (compose + where, myaddr[i + j]);
1165e93f7393Sniklas 	  where += 2;
1166e93f7393Sniklas 	}
1167e93f7393Sniklas       stickbyte (compose + where, ~check_sum);
1168e93f7393Sniklas       where += 2;
1169e93f7393Sniklas       compose[where++] = '\r';
1170e93f7393Sniklas       compose[where++] = '\n';
1171e93f7393Sniklas       compose[where++] = 0;
1172e93f7393Sniklas 
1173b725ae77Skettenis       serial_write (e7000_desc, compose, where);
1174b725ae77Skettenis       j = readchar (0);
1175b725ae77Skettenis       if (j == -1)
1176e93f7393Sniklas 	{
1177e93f7393Sniklas 	  /* This is ok - nothing there */
1178e93f7393Sniklas 	}
1179e93f7393Sniklas       else if (j == ENQ)
1180e93f7393Sniklas 	{
1181e93f7393Sniklas 	  /* Hmm, it's trying to tell us something */
1182e93f7393Sniklas 	  expect (":");
1183e93f7393Sniklas 	  error ("Error writing memory");
1184e93f7393Sniklas 	}
1185e93f7393Sniklas       else
1186e93f7393Sniklas 	{
1187b725ae77Skettenis 	  printf_unfiltered ("@%d}@", j);
1188b725ae77Skettenis 	  while ((j = readchar (0)) > 0)
1189e93f7393Sniklas 	    {
1190b725ae77Skettenis 	      printf_unfiltered ("@{%d}@", j);
1191e93f7393Sniklas 	    }
1192e93f7393Sniklas 	}
1193e93f7393Sniklas     }
1194e93f7393Sniklas 
1195e93f7393Sniklas   /* Send the trailer record */
1196e93f7393Sniklas   write_e7000 ("S70500000000FA\r");
1197e93f7393Sniklas   putchar_e7000 (CTRLZ);
1198e93f7393Sniklas   expect (ENQSTRING);
1199e93f7393Sniklas   putchar_e7000 (ACK);
1200e93f7393Sniklas   expect (":");
1201e93f7393Sniklas 
1202e93f7393Sniklas   return len;
1203e93f7393Sniklas }
1204e93f7393Sniklas 
1205e93f7393Sniklas /* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
1206e93f7393Sniklas    memory at MEMADDR.  Returns length moved.
1207e93f7393Sniklas 
1208e93f7393Sniklas    Can't use the Srecord load over ethernet, so don't use fast method
1209e93f7393Sniklas    then.  */
1210e93f7393Sniklas 
1211e93f7393Sniklas static int
e7000_write_inferior_memory(CORE_ADDR memaddr,unsigned char * myaddr,int len)1212b725ae77Skettenis e7000_write_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1213e93f7393Sniklas {
1214e93f7393Sniklas   if (len < 16 || using_tcp || using_pc)
1215e93f7393Sniklas     return write_small (memaddr, myaddr, len);
1216e93f7393Sniklas   else
1217e93f7393Sniklas     return write_large (memaddr, myaddr, len);
1218e93f7393Sniklas }
1219e93f7393Sniklas 
1220e93f7393Sniklas /* Read LEN bytes from inferior memory at MEMADDR.  Put the result
1221e93f7393Sniklas    at debugger address MYADDR.  Returns length moved.
1222e93f7393Sniklas 
1223e93f7393Sniklas    Small transactions we send
1224e93f7393Sniklas    m <addr>;l
1225e93f7393Sniklas    and receive
1226e93f7393Sniklas    00000000 12345678 ?
1227e93f7393Sniklas  */
1228e93f7393Sniklas 
1229e93f7393Sniklas static int
e7000_read_inferior_memory(CORE_ADDR memaddr,unsigned char * myaddr,int len)1230b725ae77Skettenis e7000_read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
1231e93f7393Sniklas {
1232e93f7393Sniklas   int count;
1233e93f7393Sniklas   int c;
1234e93f7393Sniklas   int i;
1235e93f7393Sniklas   char buf[200];
1236e93f7393Sniklas   /* Starting address of this pass.  */
1237e93f7393Sniklas 
1238e93f7393Sniklas /*  printf("READ INF %x %x %d\n", memaddr, myaddr, len); */
1239e93f7393Sniklas   if (((memaddr - 1) + len) < memaddr)
1240e93f7393Sniklas     {
1241e93f7393Sniklas       errno = EIO;
1242e93f7393Sniklas       return 0;
1243e93f7393Sniklas     }
1244e93f7393Sniklas 
1245b725ae77Skettenis   sprintf (buf, "m %s;l\r", paddr_nz (memaddr));
1246e93f7393Sniklas   puts_e7000debug (buf);
1247e93f7393Sniklas 
1248e93f7393Sniklas   for (count = 0; count < len; count += 4)
1249e93f7393Sniklas     {
1250e93f7393Sniklas       /* Suck away the address */
1251e93f7393Sniklas       c = gch ();
1252e93f7393Sniklas       while (c != ' ')
1253e93f7393Sniklas 	c = gch ();
1254e93f7393Sniklas       c = gch ();
1255e93f7393Sniklas       if (c == '*')
1256e93f7393Sniklas 	{			/* Some kind of error */
1257b725ae77Skettenis 	  puts_e7000debug (".\r");	/* Some errors leave us in memory input mode */
1258b725ae77Skettenis 	  expect_full_prompt ();
1259e93f7393Sniklas 	  return -1;
1260e93f7393Sniklas 	}
1261e93f7393Sniklas       while (c != ' ')
1262e93f7393Sniklas 	c = gch ();
1263e93f7393Sniklas 
1264e93f7393Sniklas       /* Now read in the data */
1265e93f7393Sniklas       for (i = 0; i < 4; i++)
1266e93f7393Sniklas 	{
1267e93f7393Sniklas 	  int b = gbyte ();
1268b725ae77Skettenis 	  if (count + i < len)
1269b725ae77Skettenis 	    {
1270e93f7393Sniklas 	      myaddr[count + i] = b;
1271e93f7393Sniklas 	    }
1272e93f7393Sniklas 	}
1273e93f7393Sniklas 
1274e93f7393Sniklas       /* Skip the trailing ? and send a . to end and a cr for more */
1275e93f7393Sniklas       gch ();
1276e93f7393Sniklas       gch ();
1277e93f7393Sniklas       if (count + 4 >= len)
1278e93f7393Sniklas 	puts_e7000debug (".\r");
1279e93f7393Sniklas       else
1280e93f7393Sniklas 	puts_e7000debug ("\r");
1281e93f7393Sniklas 
1282e93f7393Sniklas     }
1283e93f7393Sniklas   expect_prompt ();
1284e93f7393Sniklas   return len;
1285e93f7393Sniklas }
1286e93f7393Sniklas 
1287e93f7393Sniklas 
1288e93f7393Sniklas 
1289e93f7393Sniklas /*
1290e93f7393Sniklas    For large transfers we used to send
1291e93f7393Sniklas 
1292e93f7393Sniklas 
1293e93f7393Sniklas    d <addr> <endaddr>\r
1294e93f7393Sniklas 
1295e93f7393Sniklas    and receive
1296e93f7393Sniklas    <ADDRESS>           <    D   A   T   A    >               <   ASCII CODE   >
1297e93f7393Sniklas    00000000 5F FD FD FF DF 7F DF FF  01 00 01 00 02 00 08 04  "_..............."
1298e93f7393Sniklas    00000010 FF D7 FF 7F D7 F1 7F FF  00 05 00 00 08 00 40 00  "..............@."
1299e93f7393Sniklas    00000020 7F FD FF F7 7F FF FF F7  00 00 00 00 00 00 00 00  "................"
1300e93f7393Sniklas 
1301e93f7393Sniklas    A cost in chars for each transaction of 80 + 5*n-bytes.
1302e93f7393Sniklas 
1303e93f7393Sniklas    Large transactions could be done with the srecord load code, but
1304e93f7393Sniklas    there is a pause for a second before dumping starts, which slows the
1305e93f7393Sniklas    average rate down!
1306e93f7393Sniklas  */
1307e93f7393Sniklas 
1308e93f7393Sniklas static int
e7000_read_inferior_memory_large(CORE_ADDR memaddr,unsigned char * myaddr,int len)1309b725ae77Skettenis e7000_read_inferior_memory_large (CORE_ADDR memaddr, unsigned char *myaddr,
1310b725ae77Skettenis 				  int len)
1311e93f7393Sniklas {
1312e93f7393Sniklas   int count;
1313e93f7393Sniklas   int c;
1314e93f7393Sniklas   char buf[200];
1315e93f7393Sniklas 
1316e93f7393Sniklas   /* Starting address of this pass.  */
1317e93f7393Sniklas 
1318e93f7393Sniklas   if (((memaddr - 1) + len) < memaddr)
1319e93f7393Sniklas     {
1320e93f7393Sniklas       errno = EIO;
1321e93f7393Sniklas       return 0;
1322e93f7393Sniklas     }
1323e93f7393Sniklas 
1324b725ae77Skettenis   sprintf (buf, "d %s %s\r", paddr_nz (memaddr), paddr_nz (memaddr + len - 1));
1325e93f7393Sniklas   puts_e7000debug (buf);
1326e93f7393Sniklas 
1327e93f7393Sniklas   count = 0;
1328e93f7393Sniklas   c = gch ();
1329e93f7393Sniklas 
1330e93f7393Sniklas   /* skip down to the first ">" */
1331e93f7393Sniklas   while (c != '>')
1332e93f7393Sniklas     c = gch ();
1333e93f7393Sniklas   /* now skip to the end of that line */
1334e93f7393Sniklas   while (c != '\r')
1335e93f7393Sniklas     c = gch ();
1336e93f7393Sniklas   c = gch ();
1337e93f7393Sniklas 
1338e93f7393Sniklas   while (count < len)
1339e93f7393Sniklas     {
1340e93f7393Sniklas       /* get rid of any white space before the address */
1341e93f7393Sniklas       while (c <= ' ')
1342e93f7393Sniklas 	c = gch ();
1343e93f7393Sniklas 
1344e93f7393Sniklas       /* Skip the address */
1345e93f7393Sniklas       get_hex (&c);
1346e93f7393Sniklas 
1347e93f7393Sniklas       /* read in the bytes on the line */
1348e93f7393Sniklas       while (c != '"' && count < len)
1349e93f7393Sniklas 	{
1350e93f7393Sniklas 	  if (c == ' ')
1351e93f7393Sniklas 	    c = gch ();
1352e93f7393Sniklas 	  else
1353e93f7393Sniklas 	    {
1354e93f7393Sniklas 	      myaddr[count++] = get_hex (&c);
1355e93f7393Sniklas 	    }
1356e93f7393Sniklas 	}
1357e93f7393Sniklas       /* throw out the rest of the line */
1358e93f7393Sniklas       while (c != '\r')
1359e93f7393Sniklas 	c = gch ();
1360e93f7393Sniklas     }
1361e93f7393Sniklas 
1362e93f7393Sniklas   /* wait for the ":" prompt */
1363e93f7393Sniklas   while (c != ':')
1364e93f7393Sniklas     c = gch ();
1365e93f7393Sniklas 
1366e93f7393Sniklas   return len;
1367e93f7393Sniklas }
1368e93f7393Sniklas 
1369e93f7393Sniklas #if 0
1370e93f7393Sniklas 
1371e93f7393Sniklas static int
1372b725ae77Skettenis fast_but_for_the_pause_e7000_read_inferior_memory (CORE_ADDR memaddr,
1373b725ae77Skettenis 						   char *myaddr, int len)
1374e93f7393Sniklas {
1375e93f7393Sniklas   int loop;
1376e93f7393Sniklas   int c;
1377e93f7393Sniklas   char buf[200];
1378e93f7393Sniklas 
1379e93f7393Sniklas   if (((memaddr - 1) + len) < memaddr)
1380e93f7393Sniklas     {
1381e93f7393Sniklas       errno = EIO;
1382e93f7393Sniklas       return 0;
1383e93f7393Sniklas     }
1384e93f7393Sniklas 
1385e93f7393Sniklas   sprintf (buf, "is %x@%x:s\r", memaddr, len);
1386e93f7393Sniklas   puts_e7000debug (buf);
1387e93f7393Sniklas   gch ();
1388e93f7393Sniklas   c = gch ();
1389e93f7393Sniklas   if (c != ENQ)
1390e93f7393Sniklas     {
1391e93f7393Sniklas       /* Got an error */
1392e93f7393Sniklas       error ("Memory read error");
1393e93f7393Sniklas     }
1394e93f7393Sniklas   putchar_e7000 (ACK);
1395e93f7393Sniklas   expect ("SV s");
1396e93f7393Sniklas   loop = 1;
1397e93f7393Sniklas   while (loop)
1398e93f7393Sniklas     {
1399e93f7393Sniklas       int type;
1400e93f7393Sniklas       int length;
1401e93f7393Sniklas       int addr;
1402e93f7393Sniklas       int i;
1403e93f7393Sniklas 
1404e93f7393Sniklas       c = gch ();
1405e93f7393Sniklas       switch (c)
1406e93f7393Sniklas 	{
1407e93f7393Sniklas 	case ENQ:		/* ENQ, at the end */
1408e93f7393Sniklas 	  loop = 0;
1409e93f7393Sniklas 	  break;
1410e93f7393Sniklas 	case 'S':
1411e93f7393Sniklas 	  /* Start of an Srecord */
1412e93f7393Sniklas 	  type = gch ();
1413e93f7393Sniklas 	  length = gbyte ();
1414e93f7393Sniklas 	  switch (type)
1415e93f7393Sniklas 	    {
1416e93f7393Sniklas 	    case '7':		/* Termination record, ignore */
1417e93f7393Sniklas 	    case '0':
1418e93f7393Sniklas 	    case '8':
1419e93f7393Sniklas 	    case '9':
1420e93f7393Sniklas 	      /* Header record - ignore it */
1421e93f7393Sniklas 	      while (length--)
1422e93f7393Sniklas 		{
1423e93f7393Sniklas 		  gbyte ();
1424e93f7393Sniklas 		}
1425e93f7393Sniklas 	      break;
1426e93f7393Sniklas 	    case '1':
1427e93f7393Sniklas 	    case '2':
1428e93f7393Sniklas 	    case '3':
1429e93f7393Sniklas 	      {
1430e93f7393Sniklas 		int alen;
1431e93f7393Sniklas 
1432e93f7393Sniklas 		alen = type - '0' + 1;
1433e93f7393Sniklas 		addr = 0;
1434e93f7393Sniklas 		while (alen--)
1435e93f7393Sniklas 		  {
1436e93f7393Sniklas 		    addr = (addr << 8) + gbyte ();
1437e93f7393Sniklas 		    length--;
1438e93f7393Sniklas 		  }
1439e93f7393Sniklas 
1440e93f7393Sniklas 		for (i = 0; i < length - 1; i++)
1441e93f7393Sniklas 		  myaddr[i + addr - memaddr] = gbyte ();
1442e93f7393Sniklas 
1443e93f7393Sniklas 		gbyte ();	/* Ignore checksum */
1444e93f7393Sniklas 	      }
1445e93f7393Sniklas 	    }
1446e93f7393Sniklas 	}
1447e93f7393Sniklas     }
1448e93f7393Sniklas 
1449e93f7393Sniklas   putchar_e7000 (ACK);
1450e93f7393Sniklas   expect ("TOP ADDRESS =");
1451e93f7393Sniklas   expect ("END ADDRESS =");
1452e93f7393Sniklas   expect (":");
1453e93f7393Sniklas 
1454e93f7393Sniklas   return len;
1455e93f7393Sniklas }
1456e93f7393Sniklas 
1457e93f7393Sniklas #endif
1458e93f7393Sniklas 
1459b725ae77Skettenis /* Transfer LEN bytes between GDB address MYADDR and target address
1460b725ae77Skettenis    MEMADDR.  If WRITE is non-zero, transfer them to the target,
1461b725ae77Skettenis    otherwise transfer them from the target.  TARGET is unused.
1462b725ae77Skettenis 
1463b725ae77Skettenis    Returns the number of bytes transferred. */
1464b725ae77Skettenis 
1465e93f7393Sniklas static int
e7000_xfer_inferior_memory(CORE_ADDR memaddr,char * myaddr,int len,int write,struct mem_attrib * attrib,struct target_ops * target)1466b725ae77Skettenis e7000_xfer_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len,
1467b725ae77Skettenis 			    int write, struct mem_attrib *attrib,
1468b725ae77Skettenis 			    struct target_ops *target)
1469e93f7393Sniklas {
1470e93f7393Sniklas   if (write)
1471e93f7393Sniklas     return e7000_write_inferior_memory (memaddr, myaddr, len);
1472b725ae77Skettenis   else if (len < 16)
1473e93f7393Sniklas     return e7000_read_inferior_memory (memaddr, myaddr, len);
1474e93f7393Sniklas   else
1475e93f7393Sniklas     return e7000_read_inferior_memory_large (memaddr, myaddr, len);
1476e93f7393Sniklas }
1477e93f7393Sniklas 
1478e93f7393Sniklas static void
e7000_kill(void)1479b725ae77Skettenis e7000_kill (void)
1480e93f7393Sniklas {
1481e93f7393Sniklas }
1482e93f7393Sniklas 
1483e93f7393Sniklas static void
e7000_load(char * args,int from_tty)1484b725ae77Skettenis e7000_load (char *args, int from_tty)
1485e93f7393Sniklas {
1486e93f7393Sniklas   struct cleanup *old_chain;
1487e93f7393Sniklas   asection *section;
1488e93f7393Sniklas   bfd *pbfd;
1489e93f7393Sniklas   bfd_vma entry;
1490e93f7393Sniklas #define WRITESIZE 0x1000
1491e93f7393Sniklas   char buf[2 + 4 + 4 + WRITESIZE];	/* `DT' + <addr> + <len> + <data> */
1492e93f7393Sniklas   char *filename;
1493e93f7393Sniklas   int quiet;
1494e93f7393Sniklas   int nostart;
1495e93f7393Sniklas   time_t start_time, end_time;	/* Start and end times of download */
1496e93f7393Sniklas   unsigned long data_count;	/* Number of bytes transferred to memory */
1497e93f7393Sniklas   int oldtimeout = timeout;
1498e93f7393Sniklas 
1499e93f7393Sniklas   timeout = remote_timeout;
1500e93f7393Sniklas 
1501e93f7393Sniklas 
1502e93f7393Sniklas   /* FIXME! change test to test for type of download */
1503e93f7393Sniklas   if (!using_tcp)
1504e93f7393Sniklas     {
1505e93f7393Sniklas       generic_load (args, from_tty);
1506e93f7393Sniklas       return;
1507e93f7393Sniklas     }
1508e93f7393Sniklas 
1509e93f7393Sniklas   /* for direct tcp connections, we can do a fast binary download */
1510e93f7393Sniklas   buf[0] = 'D';
1511e93f7393Sniklas   buf[1] = 'T';
1512e93f7393Sniklas   quiet = 0;
1513e93f7393Sniklas   nostart = 0;
1514e93f7393Sniklas   filename = NULL;
1515e93f7393Sniklas 
1516e93f7393Sniklas   while (*args != '\000')
1517e93f7393Sniklas     {
1518e93f7393Sniklas       char *arg;
1519e93f7393Sniklas 
1520b725ae77Skettenis       while (isspace (*args))
1521b725ae77Skettenis 	args++;
1522e93f7393Sniklas 
1523e93f7393Sniklas       arg = args;
1524e93f7393Sniklas 
1525b725ae77Skettenis       while ((*args != '\000') && !isspace (*args))
1526b725ae77Skettenis 	args++;
1527e93f7393Sniklas 
1528e93f7393Sniklas       if (*args != '\000')
1529e93f7393Sniklas 	*args++ = '\000';
1530e93f7393Sniklas 
1531e93f7393Sniklas       if (*arg != '-')
1532e93f7393Sniklas 	filename = arg;
1533e93f7393Sniklas       else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
1534e93f7393Sniklas 	quiet = 1;
1535e93f7393Sniklas       else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
1536e93f7393Sniklas 	nostart = 1;
1537e93f7393Sniklas       else
1538e93f7393Sniklas 	error ("unknown option `%s'", arg);
1539e93f7393Sniklas     }
1540e93f7393Sniklas 
1541e93f7393Sniklas   if (!filename)
1542e93f7393Sniklas     filename = get_exec_file (1);
1543e93f7393Sniklas 
1544e93f7393Sniklas   pbfd = bfd_openr (filename, gnutarget);
1545e93f7393Sniklas   if (pbfd == NULL)
1546e93f7393Sniklas     {
1547e93f7393Sniklas       perror_with_name (filename);
1548e93f7393Sniklas       return;
1549e93f7393Sniklas     }
1550b725ae77Skettenis   old_chain = make_cleanup_bfd_close (pbfd);
1551e93f7393Sniklas 
1552e93f7393Sniklas   if (!bfd_check_format (pbfd, bfd_object))
1553e93f7393Sniklas     error ("\"%s\" is not an object file: %s", filename,
1554e93f7393Sniklas 	   bfd_errmsg (bfd_get_error ()));
1555e93f7393Sniklas 
1556e93f7393Sniklas   start_time = time (NULL);
1557e93f7393Sniklas   data_count = 0;
1558e93f7393Sniklas 
1559e93f7393Sniklas   puts_e7000debug ("mw\r");
1560e93f7393Sniklas 
1561e93f7393Sniklas   expect ("\nOK");
1562e93f7393Sniklas 
1563e93f7393Sniklas   for (section = pbfd->sections; section; section = section->next)
1564e93f7393Sniklas     {
1565e93f7393Sniklas       if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
1566e93f7393Sniklas 	{
1567e93f7393Sniklas 	  bfd_vma section_address;
1568e93f7393Sniklas 	  bfd_size_type section_size;
1569e93f7393Sniklas 	  file_ptr fptr;
1570e93f7393Sniklas 
1571e93f7393Sniklas 	  section_address = bfd_get_section_vma (pbfd, section);
1572*63addd46Skettenis 	  section_size = bfd_get_section_size (section);
1573e93f7393Sniklas 
1574e93f7393Sniklas 	  if (!quiet)
1575b725ae77Skettenis 	    printf_filtered ("[Loading section %s at 0x%s (%s bytes)]\n",
1576e93f7393Sniklas 			     bfd_get_section_name (pbfd, section),
1577b725ae77Skettenis 			     paddr_nz (section_address),
1578b725ae77Skettenis 			     paddr_u (section_size));
1579e93f7393Sniklas 
1580e93f7393Sniklas 	  fptr = 0;
1581e93f7393Sniklas 
1582e93f7393Sniklas 	  data_count += section_size;
1583e93f7393Sniklas 
1584e93f7393Sniklas 	  while (section_size > 0)
1585e93f7393Sniklas 	    {
1586e93f7393Sniklas 	      int count;
1587e93f7393Sniklas 	      static char inds[] = "|/-\\";
1588e93f7393Sniklas 	      static int k = 0;
1589e93f7393Sniklas 
1590e93f7393Sniklas 	      QUIT;
1591e93f7393Sniklas 
1592e93f7393Sniklas 	      count = min (section_size, WRITESIZE);
1593e93f7393Sniklas 
1594e93f7393Sniklas 	      buf[2] = section_address >> 24;
1595e93f7393Sniklas 	      buf[3] = section_address >> 16;
1596e93f7393Sniklas 	      buf[4] = section_address >> 8;
1597e93f7393Sniklas 	      buf[5] = section_address;
1598e93f7393Sniklas 
1599e93f7393Sniklas 	      buf[6] = count >> 24;
1600e93f7393Sniklas 	      buf[7] = count >> 16;
1601e93f7393Sniklas 	      buf[8] = count >> 8;
1602e93f7393Sniklas 	      buf[9] = count;
1603e93f7393Sniklas 
1604e93f7393Sniklas 	      bfd_get_section_contents (pbfd, section, buf + 10, fptr, count);
1605e93f7393Sniklas 
1606b725ae77Skettenis 	      if (serial_write (e7000_desc, buf, count + 10))
1607e93f7393Sniklas 		fprintf_unfiltered (gdb_stderr,
1608b725ae77Skettenis 				    "e7000_load: serial_write failed: %s\n",
1609e93f7393Sniklas 				    safe_strerror (errno));
1610e93f7393Sniklas 
1611e93f7393Sniklas 	      expect ("OK");
1612e93f7393Sniklas 
1613e93f7393Sniklas 	      if (!quiet)
1614e93f7393Sniklas 		{
1615e93f7393Sniklas 		  printf_unfiltered ("\r%c", inds[k++ % 4]);
1616e93f7393Sniklas 		  gdb_flush (gdb_stdout);
1617e93f7393Sniklas 		}
1618e93f7393Sniklas 
1619e93f7393Sniklas 	      section_address += count;
1620e93f7393Sniklas 	      fptr += count;
1621e93f7393Sniklas 	      section_size -= count;
1622e93f7393Sniklas 	    }
1623e93f7393Sniklas 	}
1624e93f7393Sniklas     }
1625e93f7393Sniklas 
1626e93f7393Sniklas   write_e7000 ("ED");
1627e93f7393Sniklas 
1628e93f7393Sniklas   expect_prompt ();
1629e93f7393Sniklas 
1630e93f7393Sniklas   end_time = time (NULL);
1631e93f7393Sniklas 
1632e93f7393Sniklas /* Finally, make the PC point at the start address */
1633e93f7393Sniklas 
1634e93f7393Sniklas   if (exec_bfd)
1635e93f7393Sniklas     write_pc (bfd_get_start_address (exec_bfd));
1636e93f7393Sniklas 
1637b725ae77Skettenis   inferior_ptid = null_ptid;	/* No process now */
1638e93f7393Sniklas 
1639e93f7393Sniklas /* This is necessary because many things were based on the PC at the time that
1640e93f7393Sniklas    we attached to the monitor, which is no longer valid now that we have loaded
1641e93f7393Sniklas    new code (and just changed the PC).  Another way to do this might be to call
1642e93f7393Sniklas    normal_stop, except that the stack may not be valid, and things would get
1643e93f7393Sniklas    horribly confused... */
1644e93f7393Sniklas 
1645e93f7393Sniklas   clear_symtab_users ();
1646e93f7393Sniklas 
1647e93f7393Sniklas   if (!nostart)
1648e93f7393Sniklas     {
1649e93f7393Sniklas       entry = bfd_get_start_address (pbfd);
1650e93f7393Sniklas 
1651e93f7393Sniklas       if (!quiet)
1652b725ae77Skettenis 	printf_unfiltered ("[Starting %s at 0x%s]\n", filename, paddr_nz (entry));
1653e93f7393Sniklas 
1654e93f7393Sniklas /*      start_routine (entry); */
1655e93f7393Sniklas     }
1656e93f7393Sniklas 
1657e93f7393Sniklas   report_transfer_performance (data_count, start_time, end_time);
1658e93f7393Sniklas 
1659e93f7393Sniklas   do_cleanups (old_chain);
1660e93f7393Sniklas   timeout = oldtimeout;
1661e93f7393Sniklas }
1662e93f7393Sniklas 
1663e93f7393Sniklas /* Clean up when a program exits.
1664e93f7393Sniklas 
1665e93f7393Sniklas    The program actually lives on in the remote processor's RAM, and may be
1666e93f7393Sniklas    run again without a download.  Don't leave it full of breakpoint
1667e93f7393Sniklas    instructions.  */
1668e93f7393Sniklas 
1669e93f7393Sniklas static void
e7000_mourn_inferior(void)1670b725ae77Skettenis e7000_mourn_inferior (void)
1671e93f7393Sniklas {
1672e93f7393Sniklas   remove_breakpoints ();
1673e93f7393Sniklas   unpush_target (&e7000_ops);
1674e93f7393Sniklas   generic_mourn_inferior ();	/* Do all the proper things now */
1675e93f7393Sniklas }
1676e93f7393Sniklas 
1677e93f7393Sniklas #define MAX_BREAKPOINTS 200
1678e93f7393Sniklas #ifdef  HARD_BREAKPOINTS
1679e93f7393Sniklas #define MAX_E7000DEBUG_BREAKPOINTS (BC_BREAKPOINTS ? 5 :  MAX_BREAKPOINTS)
1680e93f7393Sniklas #else
1681e93f7393Sniklas #define MAX_E7000DEBUG_BREAKPOINTS MAX_BREAKPOINTS
1682e93f7393Sniklas #endif
1683e93f7393Sniklas 
1684e93f7393Sniklas /* Since we can change to soft breakpoints dynamically, we must define
1685e93f7393Sniklas    more than enough.  Was breakaddr[MAX_E7000DEBUG_BREAKPOINTS]. */
1686b725ae77Skettenis static CORE_ADDR breakaddr[MAX_BREAKPOINTS] =
1687b725ae77Skettenis {0};
1688e93f7393Sniklas 
1689e93f7393Sniklas static int
e7000_insert_breakpoint(CORE_ADDR addr,char * shadow)1690b725ae77Skettenis e7000_insert_breakpoint (CORE_ADDR addr, char *shadow)
1691e93f7393Sniklas {
1692e93f7393Sniklas   int i;
1693e93f7393Sniklas   char buf[200];
1694b725ae77Skettenis #if 0
1695e93f7393Sniklas   static char nop[2] = NOP;
1696b725ae77Skettenis #endif
1697e93f7393Sniklas 
1698e93f7393Sniklas   for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++)
1699e93f7393Sniklas     if (breakaddr[i] == 0)
1700e93f7393Sniklas       {
1701e93f7393Sniklas 	breakaddr[i] = addr;
1702e93f7393Sniklas 	/* Save old contents, and insert a nop in the space */
1703e93f7393Sniklas #ifdef HARD_BREAKPOINTS
1704e93f7393Sniklas 	if (BC_BREAKPOINTS)
1705e93f7393Sniklas 	  {
1706b725ae77Skettenis 	    sprintf (buf, "BC%d A=%s\r", i + 1, paddr_nz (addr));
1707e93f7393Sniklas 	    puts_e7000debug (buf);
1708e93f7393Sniklas 	  }
1709e93f7393Sniklas 	else
1710e93f7393Sniklas 	  {
1711b725ae77Skettenis 	    sprintf (buf, "B %s\r", paddr_nz (addr));
1712e93f7393Sniklas 	    puts_e7000debug (buf);
1713e93f7393Sniklas 	  }
1714e93f7393Sniklas #else
1715e93f7393Sniklas #if 0
1716e93f7393Sniklas 	e7000_read_inferior_memory (addr, shadow, 2);
1717e93f7393Sniklas 	e7000_write_inferior_memory (addr, nop, 2);
1718e93f7393Sniklas #endif
1719e93f7393Sniklas 
1720e93f7393Sniklas 	sprintf (buf, "B %x\r", addr);
1721e93f7393Sniklas 	puts_e7000debug (buf);
1722e93f7393Sniklas #endif
1723e93f7393Sniklas 	expect_prompt ();
1724e93f7393Sniklas 	return 0;
1725e93f7393Sniklas       }
1726e93f7393Sniklas 
1727e93f7393Sniklas   error ("Too many breakpoints ( > %d) for the E7000\n",
1728e93f7393Sniklas 	 MAX_E7000DEBUG_BREAKPOINTS);
1729e93f7393Sniklas   return 1;
1730e93f7393Sniklas }
1731e93f7393Sniklas 
1732e93f7393Sniklas static int
e7000_remove_breakpoint(CORE_ADDR addr,char * shadow)1733b725ae77Skettenis e7000_remove_breakpoint (CORE_ADDR addr, char *shadow)
1734e93f7393Sniklas {
1735e93f7393Sniklas   int i;
1736e93f7393Sniklas   char buf[200];
1737e93f7393Sniklas 
1738e93f7393Sniklas   for (i = 0; i < MAX_E7000DEBUG_BREAKPOINTS; i++)
1739e93f7393Sniklas     if (breakaddr[i] == addr)
1740e93f7393Sniklas       {
1741e93f7393Sniklas 	breakaddr[i] = 0;
1742e93f7393Sniklas #ifdef HARD_BREAKPOINTS
1743e93f7393Sniklas 	if (BC_BREAKPOINTS)
1744e93f7393Sniklas 	  {
1745e93f7393Sniklas 	    sprintf (buf, "BC%d - \r", i + 1);
1746e93f7393Sniklas 	    puts_e7000debug (buf);
1747e93f7393Sniklas 	  }
1748e93f7393Sniklas 	else
1749e93f7393Sniklas 	  {
1750b725ae77Skettenis 	    sprintf (buf, "B - %s\r", paddr_nz (addr));
1751e93f7393Sniklas 	    puts_e7000debug (buf);
1752e93f7393Sniklas 	  }
1753e93f7393Sniklas 	expect_prompt ();
1754e93f7393Sniklas #else
1755b725ae77Skettenis 	sprintf (buf, "B - %s\r", paddr_nz (addr));
1756e93f7393Sniklas 	puts_e7000debug (buf);
1757e93f7393Sniklas 	expect_prompt ();
1758e93f7393Sniklas 
1759e93f7393Sniklas #if 0
1760e93f7393Sniklas 	/* Replace the insn under the break */
1761e93f7393Sniklas 	e7000_write_inferior_memory (addr, shadow, 2);
1762e93f7393Sniklas #endif
1763e93f7393Sniklas #endif
1764e93f7393Sniklas 
1765e93f7393Sniklas 	return 0;
1766e93f7393Sniklas       }
1767e93f7393Sniklas 
1768b725ae77Skettenis   warning ("Can't find breakpoint associated with 0x%s\n", paddr_nz (addr));
1769e93f7393Sniklas   return 1;
1770e93f7393Sniklas }
1771e93f7393Sniklas 
1772e93f7393Sniklas /* Put a command string, in args, out to STDBUG.  Output from STDBUG
1773e93f7393Sniklas    is placed on the users terminal until the prompt is seen. */
1774e93f7393Sniklas 
1775e93f7393Sniklas static void
e7000_command(char * args,int fromtty)1776b725ae77Skettenis e7000_command (char *args, int fromtty)
1777e93f7393Sniklas {
1778e93f7393Sniklas   /* FIXME: arbitrary limit on length of args.  */
1779e93f7393Sniklas   char buf[200];
1780e93f7393Sniklas 
1781e93f7393Sniklas   echo = 0;
1782e93f7393Sniklas 
1783e93f7393Sniklas   if (!e7000_desc)
1784e93f7393Sniklas     error ("e7000 target not open.");
1785e93f7393Sniklas   if (!args)
1786e93f7393Sniklas     {
1787e93f7393Sniklas       puts_e7000debug ("\r");
1788e93f7393Sniklas     }
1789e93f7393Sniklas   else
1790e93f7393Sniklas     {
1791e93f7393Sniklas       sprintf (buf, "%s\r", args);
1792e93f7393Sniklas       puts_e7000debug (buf);
1793e93f7393Sniklas     }
1794e93f7393Sniklas 
1795e93f7393Sniklas   echo++;
1796e93f7393Sniklas   ctrl_c = 2;
1797e93f7393Sniklas   expect_full_prompt ();
1798e93f7393Sniklas   echo--;
1799e93f7393Sniklas   ctrl_c = 0;
1800e93f7393Sniklas   printf_unfiltered ("\n");
1801e93f7393Sniklas 
1802e93f7393Sniklas   /* Who knows what the command did... */
1803e93f7393Sniklas   registers_changed ();
1804e93f7393Sniklas }
1805e93f7393Sniklas 
1806e93f7393Sniklas 
1807e93f7393Sniklas static void
e7000_drain_command(char * args,int fromtty)1808b725ae77Skettenis e7000_drain_command (char *args, int fromtty)
1809e93f7393Sniklas {
1810e93f7393Sniklas   int c;
1811e93f7393Sniklas 
1812e93f7393Sniklas   puts_e7000debug ("end\r");
1813e93f7393Sniklas   putchar_e7000 (CTRLC);
1814e93f7393Sniklas 
1815b725ae77Skettenis   while ((c = readchar (1)) != -1)
1816e93f7393Sniklas     {
1817e93f7393Sniklas       if (quit_flag)
1818e93f7393Sniklas 	{
1819e93f7393Sniklas 	  putchar_e7000 (CTRLC);
1820e93f7393Sniklas 	  quit_flag = 0;
1821e93f7393Sniklas 	}
1822e93f7393Sniklas       if (c > ' ' && c < 127)
1823b725ae77Skettenis 	printf_unfiltered ("%c", c & 0xff);
1824e93f7393Sniklas       else
1825b725ae77Skettenis 	printf_unfiltered ("<%x>", c & 0xff);
1826e93f7393Sniklas     }
1827e93f7393Sniklas }
1828e93f7393Sniklas 
1829e93f7393Sniklas #define NITEMS 7
1830e93f7393Sniklas 
1831e93f7393Sniklas static int
why_stop(void)1832b725ae77Skettenis why_stop (void)
1833e93f7393Sniklas {
1834b725ae77Skettenis   static char *strings[NITEMS] =
1835b725ae77Skettenis   {
1836e93f7393Sniklas     "STEP NORMAL",
1837e93f7393Sniklas     "BREAK POINT",
1838e93f7393Sniklas     "BREAK KEY",
1839e93f7393Sniklas     "BREAK CONDI",
1840e93f7393Sniklas     "CYCLE ACCESS",
1841e93f7393Sniklas     "ILLEGAL INSTRUCTION",
1842e93f7393Sniklas     "WRITE PROTECT",
1843e93f7393Sniklas   };
1844e93f7393Sniklas   char *p[NITEMS];
1845e93f7393Sniklas   int c;
1846e93f7393Sniklas   int i;
1847e93f7393Sniklas 
1848e93f7393Sniklas   for (i = 0; i < NITEMS; ++i)
1849e93f7393Sniklas     p[i] = strings[i];
1850e93f7393Sniklas 
1851e93f7393Sniklas   c = gch ();
1852e93f7393Sniklas   while (1)
1853e93f7393Sniklas     {
1854e93f7393Sniklas       for (i = 0; i < NITEMS; i++)
1855e93f7393Sniklas 	{
1856e93f7393Sniklas 	  if (c == *(p[i]))
1857e93f7393Sniklas 	    {
1858e93f7393Sniklas 	      p[i]++;
1859e93f7393Sniklas 	      if (*(p[i]) == 0)
1860e93f7393Sniklas 		{
1861e93f7393Sniklas 		  /* found one of the choices */
1862e93f7393Sniklas 		  return i;
1863e93f7393Sniklas 		}
1864e93f7393Sniklas 	    }
1865e93f7393Sniklas 	  else
1866e93f7393Sniklas 	    p[i] = strings[i];
1867e93f7393Sniklas 	}
1868e93f7393Sniklas 
1869e93f7393Sniklas       c = gch ();
1870e93f7393Sniklas     }
1871e93f7393Sniklas }
1872e93f7393Sniklas 
1873e93f7393Sniklas /* Suck characters, if a string match, then return the strings index
1874e93f7393Sniklas    otherwise echo them.  */
1875e93f7393Sniklas 
1876b725ae77Skettenis static int
expect_n(char ** strings)1877b725ae77Skettenis expect_n (char **strings)
1878e93f7393Sniklas {
1879e93f7393Sniklas   char *(ptr[10]);
1880e93f7393Sniklas   int n;
1881e93f7393Sniklas   int c;
1882e93f7393Sniklas   char saveaway[100];
1883e93f7393Sniklas   char *buffer = saveaway;
1884e93f7393Sniklas   /* Count number of expect strings  */
1885e93f7393Sniklas 
1886e93f7393Sniklas   for (n = 0; strings[n]; n++)
1887e93f7393Sniklas     {
1888e93f7393Sniklas       ptr[n] = strings[n];
1889e93f7393Sniklas     }
1890e93f7393Sniklas 
1891e93f7393Sniklas   while (1)
1892e93f7393Sniklas     {
1893e93f7393Sniklas       int i;
1894e93f7393Sniklas       int gotone = 0;
1895e93f7393Sniklas 
1896b725ae77Skettenis       c = readchar (1);
1897b725ae77Skettenis       if (c == -1)
1898e93f7393Sniklas 	{
1899e93f7393Sniklas 	  printf_unfiltered ("[waiting for e7000...]\n");
1900e93f7393Sniklas 	}
1901e93f7393Sniklas #ifdef __GO32__
1902e93f7393Sniklas       if (kbhit ())
1903e93f7393Sniklas 	{
1904e93f7393Sniklas 	  int k = getkey ();
1905e93f7393Sniklas 
1906e93f7393Sniklas 	  if (k == 1)
1907e93f7393Sniklas 	    quit_flag = 1;
1908e93f7393Sniklas 	}
1909e93f7393Sniklas #endif
1910e93f7393Sniklas       if (quit_flag)
1911e93f7393Sniklas 	{
1912e93f7393Sniklas 	  putchar_e7000 (CTRLC);	/* interrupt the running program */
1913e93f7393Sniklas 	  quit_flag = 0;
1914e93f7393Sniklas 	}
1915e93f7393Sniklas 
1916e93f7393Sniklas       for (i = 0; i < n; i++)
1917e93f7393Sniklas 	{
1918e93f7393Sniklas 	  if (c == ptr[i][0])
1919e93f7393Sniklas 	    {
1920e93f7393Sniklas 	      ptr[i]++;
1921e93f7393Sniklas 	      if (ptr[i][0] == 0)
1922e93f7393Sniklas 		{
1923e93f7393Sniklas 		  /* Gone all the way */
1924e93f7393Sniklas 		  return i;
1925e93f7393Sniklas 		}
1926e93f7393Sniklas 	      gotone = 1;
1927e93f7393Sniklas 	    }
1928e93f7393Sniklas 	  else
1929e93f7393Sniklas 	    {
1930e93f7393Sniklas 	      ptr[i] = strings[i];
1931e93f7393Sniklas 	    }
1932e93f7393Sniklas 	}
1933e93f7393Sniklas 
1934e93f7393Sniklas       if (gotone)
1935e93f7393Sniklas 	{
1936e93f7393Sniklas 	  /* Save it up incase we find that there was no match */
1937e93f7393Sniklas 	  *buffer++ = c;
1938e93f7393Sniklas 	}
1939e93f7393Sniklas       else
1940e93f7393Sniklas 	{
1941e93f7393Sniklas 	  if (buffer != saveaway)
1942e93f7393Sniklas 	    {
1943e93f7393Sniklas 	      *buffer++ = 0;
1944b725ae77Skettenis 	      printf_unfiltered ("%s", buffer);
1945e93f7393Sniklas 	      buffer = saveaway;
1946e93f7393Sniklas 	    }
1947b725ae77Skettenis 	  if (c != -1)
1948e93f7393Sniklas 	    {
1949b725ae77Skettenis 	      putchar_unfiltered (c);
1950b725ae77Skettenis 	      gdb_flush (gdb_stdout);
1951e93f7393Sniklas 	    }
1952e93f7393Sniklas 	}
1953e93f7393Sniklas     }
1954e93f7393Sniklas }
1955e93f7393Sniklas 
1956e93f7393Sniklas /* We subtract two from the pc here rather than use
1957e93f7393Sniklas    DECR_PC_AFTER_BREAK since the e7000 doesn't always add two to the
1958e93f7393Sniklas    pc, and the simulators never do. */
1959e93f7393Sniklas 
1960e93f7393Sniklas static void
sub2_from_pc(void)1961b725ae77Skettenis sub2_from_pc (void)
1962e93f7393Sniklas {
1963e93f7393Sniklas   char buf[4];
1964e93f7393Sniklas   char buf2[200];
1965e93f7393Sniklas 
1966e93f7393Sniklas   store_signed_integer (buf,
1967*63addd46Skettenis 			register_size (current_gdbarch, PC_REGNUM),
1968e93f7393Sniklas 			read_register (PC_REGNUM) - 2);
1969*63addd46Skettenis   regcache_raw_supply (current_regcache, PC_REGNUM, buf);
1970b725ae77Skettenis   sprintf (buf2, ".PC %s\r", phex_nz (read_register (PC_REGNUM), 0));
1971e93f7393Sniklas   puts_e7000debug (buf2);
1972e93f7393Sniklas }
1973e93f7393Sniklas 
1974e93f7393Sniklas #define WAS_SLEEP 0
1975e93f7393Sniklas #define WAS_INT 1
1976e93f7393Sniklas #define WAS_RUNNING 2
1977e93f7393Sniklas #define WAS_OTHER 3
1978e93f7393Sniklas 
1979b725ae77Skettenis static char *estrings[] =
1980b725ae77Skettenis {
1981e93f7393Sniklas   "** SLEEP",
1982e93f7393Sniklas   "BREAK !",
1983e93f7393Sniklas   "** PC",
1984e93f7393Sniklas   "PC",
1985e93f7393Sniklas   NULL
1986e93f7393Sniklas };
1987e93f7393Sniklas 
1988e93f7393Sniklas /* Wait until the remote machine stops, then return, storing status in
1989e93f7393Sniklas    STATUS just as `wait' would.  */
1990e93f7393Sniklas 
1991b725ae77Skettenis static ptid_t
e7000_wait(ptid_t ptid,struct target_waitstatus * status)1992b725ae77Skettenis e7000_wait (ptid_t ptid, struct target_waitstatus *status)
1993e93f7393Sniklas {
1994e93f7393Sniklas   int stop_reason;
1995e93f7393Sniklas   int regno;
1996e93f7393Sniklas   int running_count = 0;
1997e93f7393Sniklas   int had_sleep = 0;
1998e93f7393Sniklas   int loop = 1;
1999b725ae77Skettenis   char *wanted_nopc = NULL;
2000e93f7393Sniklas 
2001e93f7393Sniklas   /* Then echo chars until PC= string seen */
2002e93f7393Sniklas   gch ();			/* Drop cr */
2003e93f7393Sniklas   gch ();			/* and space */
2004e93f7393Sniklas 
2005e93f7393Sniklas   while (loop)
2006e93f7393Sniklas     {
2007e93f7393Sniklas       switch (expect_n (estrings))
2008e93f7393Sniklas 	{
2009e93f7393Sniklas 	case WAS_OTHER:
2010e93f7393Sniklas 	  /* how did this happen ? */
2011e93f7393Sniklas 	  loop = 0;
2012e93f7393Sniklas 	  break;
2013e93f7393Sniklas 	case WAS_SLEEP:
2014e93f7393Sniklas 	  had_sleep = 1;
2015e93f7393Sniklas 	  putchar_e7000 (CTRLC);
2016e93f7393Sniklas 	  loop = 0;
2017e93f7393Sniklas 	  break;
2018e93f7393Sniklas 	case WAS_INT:
2019e93f7393Sniklas 	  loop = 0;
2020e93f7393Sniklas 	  break;
2021e93f7393Sniklas 	case WAS_RUNNING:
2022e93f7393Sniklas 	  running_count++;
2023e93f7393Sniklas 	  if (running_count == 20)
2024e93f7393Sniklas 	    {
2025e93f7393Sniklas 	      printf_unfiltered ("[running...]\n");
2026e93f7393Sniklas 	      running_count = 0;
2027e93f7393Sniklas 	    }
2028e93f7393Sniklas 	  break;
2029e93f7393Sniklas 	default:
2030e93f7393Sniklas 	  /* error? */
2031e93f7393Sniklas 	  break;
2032e93f7393Sniklas 	}
2033e93f7393Sniklas     }
2034e93f7393Sniklas 
2035e93f7393Sniklas   /* Skip till the PC= */
2036e93f7393Sniklas   expect ("=");
2037e93f7393Sniklas 
2038b725ae77Skettenis   if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
2039b725ae77Skettenis     {
2040b725ae77Skettenis       wanted_nopc = want_nopc_sh;
2041b725ae77Skettenis       switch (TARGET_ARCHITECTURE->mach)
2042b725ae77Skettenis 	{
2043b725ae77Skettenis 	case bfd_mach_sh3:
2044b725ae77Skettenis 	case bfd_mach_sh3e:
2045b725ae77Skettenis 	case bfd_mach_sh4:
2046b725ae77Skettenis 	  wanted_nopc = want_nopc_sh3;
2047b725ae77Skettenis 	}
2048b725ae77Skettenis     }
2049b725ae77Skettenis   if (TARGET_ARCHITECTURE->arch == bfd_arch_h8300)
2050b725ae77Skettenis     {
2051b725ae77Skettenis       wanted_nopc = want_nopc_h8300h;
2052b725ae77Skettenis       switch (TARGET_ARCHITECTURE->mach)
2053b725ae77Skettenis 	{
2054b725ae77Skettenis 	case bfd_mach_h8300s:
2055b725ae77Skettenis 	case bfd_mach_h8300sn:
2056b725ae77Skettenis 	case bfd_mach_h8300sx:
2057b725ae77Skettenis 	case bfd_mach_h8300sxn:
2058b725ae77Skettenis 	  wanted_nopc = want_nopc_h8300s;
2059b725ae77Skettenis 	}
2060b725ae77Skettenis     }
2061b725ae77Skettenis   fetch_regs_from_dump (gch, wanted_nopc);
2062e93f7393Sniklas 
2063e93f7393Sniklas   /* And supply the extra ones the simulator uses */
2064e93f7393Sniklas   for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
2065e93f7393Sniklas     {
2066e93f7393Sniklas       int buf = 0;
2067*63addd46Skettenis       regcache_raw_supply (current_regcache, regno, (char *) &buf);
2068e93f7393Sniklas     }
2069e93f7393Sniklas 
2070e93f7393Sniklas   stop_reason = why_stop ();
2071e93f7393Sniklas   expect_full_prompt ();
2072e93f7393Sniklas 
2073e93f7393Sniklas   status->kind = TARGET_WAITKIND_STOPPED;
2074e93f7393Sniklas   status->value.sig = TARGET_SIGNAL_TRAP;
2075e93f7393Sniklas 
2076e93f7393Sniklas   switch (stop_reason)
2077e93f7393Sniklas     {
2078e93f7393Sniklas     case 1:			/* Breakpoint */
2079e93f7393Sniklas       write_pc (read_pc ());	/* PC is always off by 2 for breakpoints */
2080e93f7393Sniklas       status->value.sig = TARGET_SIGNAL_TRAP;
2081e93f7393Sniklas       break;
2082e93f7393Sniklas     case 0:			/* Single step */
2083e93f7393Sniklas       status->value.sig = TARGET_SIGNAL_TRAP;
2084e93f7393Sniklas       break;
2085e93f7393Sniklas     case 2:			/* Interrupt */
2086e93f7393Sniklas       if (had_sleep)
2087e93f7393Sniklas 	{
2088e93f7393Sniklas 	  status->value.sig = TARGET_SIGNAL_TRAP;
2089e93f7393Sniklas 	  sub2_from_pc ();
2090e93f7393Sniklas 	}
2091e93f7393Sniklas       else
2092e93f7393Sniklas 	{
2093e93f7393Sniklas 	  status->value.sig = TARGET_SIGNAL_INT;
2094e93f7393Sniklas 	}
2095e93f7393Sniklas       break;
2096e93f7393Sniklas     case 3:
2097e93f7393Sniklas       break;
2098e93f7393Sniklas     case 4:
2099e93f7393Sniklas       printf_unfiltered ("a cycle address error?\n");
2100e93f7393Sniklas       status->value.sig = TARGET_SIGNAL_UNKNOWN;
2101e93f7393Sniklas       break;
2102e93f7393Sniklas     case 5:
2103e93f7393Sniklas       status->value.sig = TARGET_SIGNAL_ILL;
2104e93f7393Sniklas       break;
2105e93f7393Sniklas     case 6:
2106e93f7393Sniklas       status->value.sig = TARGET_SIGNAL_SEGV;
2107e93f7393Sniklas       break;
2108e93f7393Sniklas     case 7:			/* Anything else (NITEMS + 1) */
2109e93f7393Sniklas       printf_unfiltered ("a write protect error?\n");
2110e93f7393Sniklas       status->value.sig = TARGET_SIGNAL_UNKNOWN;
2111e93f7393Sniklas       break;
2112e93f7393Sniklas     default:
2113e93f7393Sniklas       /* Get the user's attention - this should never happen. */
2114b725ae77Skettenis       internal_error (__FILE__, __LINE__, "failed internal consistency check");
2115e93f7393Sniklas     }
2116e93f7393Sniklas 
2117b725ae77Skettenis   return inferior_ptid;
2118e93f7393Sniklas }
2119e93f7393Sniklas 
2120e93f7393Sniklas /* Stop the running program.  */
2121e93f7393Sniklas 
2122e93f7393Sniklas static void
e7000_stop(void)2123b725ae77Skettenis e7000_stop (void)
2124e93f7393Sniklas {
2125e93f7393Sniklas   /* Sending a ^C is supposed to stop the running program.  */
2126e93f7393Sniklas   putchar_e7000 (CTRLC);
2127e93f7393Sniklas }
2128e93f7393Sniklas 
2129e93f7393Sniklas /* Define the target subroutine names. */
2130e93f7393Sniklas 
2131b725ae77Skettenis struct target_ops e7000_ops;
2132b725ae77Skettenis 
2133b725ae77Skettenis static void
init_e7000_ops(void)2134b725ae77Skettenis init_e7000_ops (void)
2135e93f7393Sniklas {
2136b725ae77Skettenis   e7000_ops.to_shortname = "e7000";
2137b725ae77Skettenis   e7000_ops.to_longname = "Remote Renesas e7000 target";
2138b725ae77Skettenis   e7000_ops.to_doc = "Use a remote Renesas e7000 ICE connected by a serial line;\n\
2139e93f7393Sniklas or a network connection.\n\
2140e93f7393Sniklas Arguments are the name of the device for the serial line,\n\
2141e93f7393Sniklas the speed to connect at in bits per second.\n\
2142e93f7393Sniklas eg\n\
2143e93f7393Sniklas target e7000 /dev/ttya 9600\n\
2144b725ae77Skettenis target e7000 foobar";
2145b725ae77Skettenis   e7000_ops.to_open = e7000_open;
2146b725ae77Skettenis   e7000_ops.to_close = e7000_close;
2147b725ae77Skettenis   e7000_ops.to_detach = e7000_detach;
2148b725ae77Skettenis   e7000_ops.to_resume = e7000_resume;
2149b725ae77Skettenis   e7000_ops.to_wait = e7000_wait;
2150b725ae77Skettenis   e7000_ops.to_fetch_registers = e7000_fetch_register;
2151b725ae77Skettenis   e7000_ops.to_store_registers = e7000_store_register;
2152b725ae77Skettenis   e7000_ops.to_prepare_to_store = e7000_prepare_to_store;
2153*63addd46Skettenis   e7000_ops.deprecated_xfer_memory = e7000_xfer_inferior_memory;
2154b725ae77Skettenis   e7000_ops.to_files_info = e7000_files_info;
2155b725ae77Skettenis   e7000_ops.to_insert_breakpoint = e7000_insert_breakpoint;
2156b725ae77Skettenis   e7000_ops.to_remove_breakpoint = e7000_remove_breakpoint;
2157b725ae77Skettenis   e7000_ops.to_kill = e7000_kill;
2158b725ae77Skettenis   e7000_ops.to_load = e7000_load;
2159b725ae77Skettenis   e7000_ops.to_create_inferior = e7000_create_inferior;
2160b725ae77Skettenis   e7000_ops.to_mourn_inferior = e7000_mourn_inferior;
2161b725ae77Skettenis   e7000_ops.to_stop = e7000_stop;
2162b725ae77Skettenis   e7000_ops.to_stratum = process_stratum;
2163b725ae77Skettenis   e7000_ops.to_has_all_memory = 1;
2164b725ae77Skettenis   e7000_ops.to_has_memory = 1;
2165b725ae77Skettenis   e7000_ops.to_has_stack = 1;
2166b725ae77Skettenis   e7000_ops.to_has_registers = 1;
2167b725ae77Skettenis   e7000_ops.to_has_execution = 1;
2168b725ae77Skettenis   e7000_ops.to_magic = OPS_MAGIC;
2169e93f7393Sniklas };
2170e93f7393Sniklas 
2171b725ae77Skettenis extern initialize_file_ftype _initialize_remote_e7000; /* -Wmissing-prototypes */
2172b725ae77Skettenis 
2173e93f7393Sniklas void
_initialize_remote_e7000(void)2174b725ae77Skettenis _initialize_remote_e7000 (void)
2175e93f7393Sniklas {
2176b725ae77Skettenis   init_e7000_ops ();
2177e93f7393Sniklas   add_target (&e7000_ops);
2178e93f7393Sniklas 
2179b725ae77Skettenis   add_com ("e7000", class_obscure, e7000_command,
2180e93f7393Sniklas 	   "Send a command to the e7000 monitor.");
2181e93f7393Sniklas 
2182b725ae77Skettenis   add_com ("ftplogin", class_obscure, e7000_login_command,
2183e93f7393Sniklas 	   "Login to machine and change to directory.");
2184e93f7393Sniklas 
2185b725ae77Skettenis   add_com ("ftpload", class_obscure, e7000_ftp_command,
2186e93f7393Sniklas 	   "Fetch and load a file from previously described place.");
2187e93f7393Sniklas 
2188e93f7393Sniklas   add_com ("drain", class_obscure, e7000_drain_command,
2189e93f7393Sniklas 	   "Drain pending e7000 text buffers.");
2190e93f7393Sniklas 
2191*63addd46Skettenis   deprecated_add_show_from_set
2192*63addd46Skettenis     (add_set_cmd ("usehardbreakpoints", no_class,
2193*63addd46Skettenis 		  var_integer, (char *) &use_hard_breakpoints, "\
2194*63addd46Skettenis Set use of hardware breakpoints for all breakpoints.\n", &setlist),
2195e93f7393Sniklas      &showlist);
2196e93f7393Sniklas }
2197