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