OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [remote-e7000.c] - Diff between revs 105 and 1765

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 105 Rev 1765
/* Remote debugging interface for Hitachi E7000 ICE, for GDB
/* Remote debugging interface for Hitachi E7000 ICE, for GDB
   Copyright 1993, 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
   Copyright 1993, 1994, 1996, 1997, 1998 Free Software Foundation, Inc.
   Contributed by Cygnus Support.
   Contributed by Cygnus Support.
 
 
   Written by Steve Chamberlain for Cygnus Support.
   Written by Steve Chamberlain for Cygnus Support.
 
 
   This file is part of GDB.
   This file is part of GDB.
 
 
   This program is free software; you can redistribute it and/or modify
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   (at your option) any later version.
 
 
   This program is distributed in the hope that it will be useful,
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   GNU General Public License for more details.
 
 
   You should have received a copy of the GNU General Public License
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */
   Boston, MA 02111-1307, USA.  */
 
 
/* The E7000 is an in-circuit emulator for the Hitachi H8/300-H and
/* The E7000 is an in-circuit emulator for the Hitachi H8/300-H and
   Hitachi-SH processor.  It has serial port and a lan port.
   Hitachi-SH processor.  It has serial port and a lan port.
 
 
   The monitor command set makes it difficult to load large ammounts of
   The monitor command set makes it difficult to load large ammounts of
   data over the lan without using ftp - so try not to issue load
   data over the lan without using ftp - so try not to issue load
   commands when communicating over ethernet; use the ftpload command.
   commands when communicating over ethernet; use the ftpload command.
 
 
   The monitor pauses for a second when dumping srecords to the serial
   The monitor pauses for a second when dumping srecords to the serial
   line too, so we use a slower per byte mechanism but without the
   line too, so we use a slower per byte mechanism but without the
   startup overhead.  Even so, it's pretty slow... */
   startup overhead.  Even so, it's pretty slow... */
 
 
#include "defs.h"
#include "defs.h"
#include "gdbcore.h"
#include "gdbcore.h"
#include "gdbarch.h"
#include "gdbarch.h"
#include "inferior.h"
#include "inferior.h"
#include "target.h"
#include "target.h"
#include "gdb_wait.h"
#include "gdb_wait.h"
#include "value.h"
#include "value.h"
#include "command.h"
#include "command.h"
#include <signal.h>
#include <signal.h>
#include "gdb_string.h"
#include "gdb_string.h"
#include "gdbcmd.h"
#include "gdbcmd.h"
#include <sys/types.h>
#include <sys/types.h>
#include "serial.h"
#include "serial.h"
#include "remote-utils.h"
#include "remote-utils.h"
#include "symfile.h"
#include "symfile.h"
#include <time.h>
#include <time.h>
#include <ctype.h>
#include <ctype.h>
 
 
 
 
#if 1
#if 1
#define HARD_BREAKPOINTS        /* Now handled by set option. */
#define HARD_BREAKPOINTS        /* Now handled by set option. */
#define BC_BREAKPOINTS use_hard_breakpoints
#define BC_BREAKPOINTS use_hard_breakpoints
#endif
#endif
 
 
#define CTRLC 0x03
#define CTRLC 0x03
#define ENQ  0x05
#define ENQ  0x05
#define ACK  0x06
#define ACK  0x06
#define CTRLZ 0x1a
#define CTRLZ 0x1a
 
 
extern void notice_quit PARAMS ((void));
extern void notice_quit PARAMS ((void));
 
 
extern void report_transfer_performance PARAMS ((unsigned long,
extern void report_transfer_performance PARAMS ((unsigned long,
                                                 time_t, time_t));
                                                 time_t, time_t));
 
 
extern char *sh_processor_type;
extern char *sh_processor_type;
 
 
/* Local function declarations.  */
/* Local function declarations.  */
 
 
static void e7000_close PARAMS ((int));
static void e7000_close PARAMS ((int));
 
 
static void e7000_fetch_register PARAMS ((int));
static void e7000_fetch_register PARAMS ((int));
 
 
static void e7000_store_register PARAMS ((int));
static void e7000_store_register PARAMS ((int));
 
 
static void e7000_command PARAMS ((char *, int));
static void e7000_command PARAMS ((char *, int));
 
 
static void e7000_login_command PARAMS ((char *, int));
static void e7000_login_command PARAMS ((char *, int));
 
 
static void e7000_ftp_command PARAMS ((char *, int));
static void e7000_ftp_command PARAMS ((char *, int));
 
 
static void e7000_drain_command PARAMS ((char *, int));
static void e7000_drain_command PARAMS ((char *, int));
 
 
static void expect PARAMS ((char *));
static void expect PARAMS ((char *));
 
 
static void expect_full_prompt PARAMS ((void));
static void expect_full_prompt PARAMS ((void));
 
 
static void expect_prompt PARAMS ((void));
static void expect_prompt PARAMS ((void));
 
 
static int e7000_parse_device PARAMS ((char *args, char *dev_name,
static int e7000_parse_device PARAMS ((char *args, char *dev_name,
                                       int baudrate));
                                       int baudrate));
/* Variables. */
/* Variables. */
 
 
static serial_t e7000_desc;
static serial_t e7000_desc;
 
 
/* Allow user to chose between using hardware breakpoints or memory. */
/* Allow user to chose between using hardware breakpoints or memory. */
static int use_hard_breakpoints = 0;     /* use sw breakpoints by default */
static int use_hard_breakpoints = 0;     /* use sw breakpoints by default */
 
 
/* Nonzero if using the tcp serial driver.  */
/* Nonzero if using the tcp serial driver.  */
 
 
static int using_tcp;           /* direct tcp connection to target */
static int using_tcp;           /* direct tcp connection to target */
static int using_tcp_remote;    /* indirect connection to target
static int using_tcp_remote;    /* indirect connection to target
                                   via tcp to controller */
                                   via tcp to controller */
 
 
/* Nonzero if using the pc isa card.  */
/* Nonzero if using the pc isa card.  */
 
 
static int using_pc;
static int using_pc;
 
 
extern struct target_ops e7000_ops;     /* Forward declaration */
extern struct target_ops e7000_ops;     /* Forward declaration */
 
 
char *ENQSTRING = "\005";
char *ENQSTRING = "\005";
 
 
/* Nonzero if some routine (as opposed to the user) wants echoing.
/* Nonzero if some routine (as opposed to the user) wants echoing.
   FIXME: Do this reentrantly with an extra parameter.  */
   FIXME: Do this reentrantly with an extra parameter.  */
 
 
static int echo;
static int echo;
 
 
static int ctrl_c;
static int ctrl_c;
 
 
static int timeout = 20;
static int timeout = 20;
 
 
/* Send data to e7000debug.  */
/* Send data to e7000debug.  */
 
 
static void
static void
puts_e7000debug (buf)
puts_e7000debug (buf)
     char *buf;
     char *buf;
{
{
  if (!e7000_desc)
  if (!e7000_desc)
    error ("Use \"target e7000 ...\" first.");
    error ("Use \"target e7000 ...\" first.");
 
 
  if (remote_debug)
  if (remote_debug)
    printf_unfiltered ("Sending %s\n", buf);
    printf_unfiltered ("Sending %s\n", buf);
 
 
  if (SERIAL_WRITE (e7000_desc, buf, strlen (buf)))
  if (SERIAL_WRITE (e7000_desc, buf, strlen (buf)))
    fprintf_unfiltered (gdb_stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
    fprintf_unfiltered (gdb_stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
 
 
  /* And expect to see it echoed, unless using the pc interface */
  /* And expect to see it echoed, unless using the pc interface */
#if 0
#if 0
  if (!using_pc)
  if (!using_pc)
#endif
#endif
    expect (buf);
    expect (buf);
}
}
 
 
static void
static void
putchar_e7000 (x)
putchar_e7000 (x)
     int x;
     int x;
{
{
  char b[1];
  char b[1];
 
 
  b[0] = x;
  b[0] = x;
  SERIAL_WRITE (e7000_desc, b, 1);
  SERIAL_WRITE (e7000_desc, b, 1);
}
}
 
 
static void
static void
write_e7000 (s)
write_e7000 (s)
     char *s;
     char *s;
{
{
  SERIAL_WRITE (e7000_desc, s, strlen (s));
  SERIAL_WRITE (e7000_desc, s, strlen (s));
}
}
 
 
static int
static int
normal (x)
normal (x)
     int x;
     int x;
{
{
  if (x == '\n')
  if (x == '\n')
    return '\r';
    return '\r';
  return x;
  return x;
}
}
 
 
/* Read a character from the remote system, doing all the fancy timeout
/* Read a character from the remote system, doing all the fancy timeout
   stuff.  Handles serial errors and EOF.  If TIMEOUT == 0, and no chars,
   stuff.  Handles serial errors and EOF.  If TIMEOUT == 0, and no chars,
   returns -1, else returns next char.  Discards chars > 127.  */
   returns -1, else returns next char.  Discards chars > 127.  */
 
 
static int
static int
readchar (timeout)
readchar (timeout)
     int timeout;
     int timeout;
{
{
  int c;
  int c;
 
 
  do
  do
    {
    {
      c = SERIAL_READCHAR (e7000_desc, timeout);
      c = SERIAL_READCHAR (e7000_desc, timeout);
    }
    }
  while (c > 127);
  while (c > 127);
 
 
  if (c == SERIAL_TIMEOUT)
  if (c == SERIAL_TIMEOUT)
    {
    {
      if (timeout == 0)
      if (timeout == 0)
        return -1;
        return -1;
      echo = 0;
      echo = 0;
      error ("Timeout reading from remote system.");
      error ("Timeout reading from remote system.");
    }
    }
  else if (c < 0)
  else if (c < 0)
    error ("Serial communication error");
    error ("Serial communication error");
 
 
  if (remote_debug)
  if (remote_debug)
    {
    {
      putchar_unfiltered (c);
      putchar_unfiltered (c);
      gdb_flush (gdb_stdout);
      gdb_flush (gdb_stdout);
    }
    }
 
 
  return normal (c);
  return normal (c);
}
}
 
 
#if 0
#if 0
char *
char *
tl (x)
tl (x)
{
{
  static char b[8][10];
  static char b[8][10];
  static int p;
  static int p;
 
 
  p++;
  p++;
  p &= 7;
  p &= 7;
  if (x >= ' ')
  if (x >= ' ')
    {
    {
      b[p][0] = x;
      b[p][0] = x;
      b[p][1] = 0;
      b[p][1] = 0;
    }
    }
  else
  else
    {
    {
      sprintf (b[p], "<%d>", x);
      sprintf (b[p], "<%d>", x);
    }
    }
 
 
  return b[p];
  return b[p];
}
}
#endif
#endif
 
 
/* Scan input from the remote system, until STRING is found.  If
/* Scan input from the remote system, until STRING is found.  If
   DISCARD is non-zero, then discard non-matching input, else print it
   DISCARD is non-zero, then discard non-matching input, else print it
   out.  Let the user break out immediately.  */
   out.  Let the user break out immediately.  */
 
 
static void
static void
expect (string)
expect (string)
     char *string;
     char *string;
{
{
  char *p = string;
  char *p = string;
  int c;
  int c;
  int nl = 0;
  int nl = 0;
 
 
  while (1)
  while (1)
    {
    {
      c = readchar (timeout);
      c = readchar (timeout);
#if 0
#if 0
      notice_quit ();
      notice_quit ();
      if (quit_flag == 1)
      if (quit_flag == 1)
        {
        {
          if (ctrl_c)
          if (ctrl_c)
            {
            {
              putchar_e7000 (CTRLC);
              putchar_e7000 (CTRLC);
              --ctrl_c;
              --ctrl_c;
            }
            }
          else
          else
            {
            {
              quit ();
              quit ();
            }
            }
        }
        }
#endif
#endif
 
 
      if (echo)
      if (echo)
        {
        {
          if (c == '\r' || c == '\n')
          if (c == '\r' || c == '\n')
            {
            {
              if (!nl)
              if (!nl)
                putchar_unfiltered ('\n');
                putchar_unfiltered ('\n');
              nl = 1;
              nl = 1;
            }
            }
          else
          else
            {
            {
              nl = 0;
              nl = 0;
              putchar_unfiltered (c);
              putchar_unfiltered (c);
            }
            }
          gdb_flush (gdb_stdout);
          gdb_flush (gdb_stdout);
        }
        }
      if (normal (c) == normal (*p++))
      if (normal (c) == normal (*p++))
        {
        {
          if (*p == '\0')
          if (*p == '\0')
            return;
            return;
        }
        }
      else
      else
        {
        {
          p = string;
          p = string;
 
 
          if (normal (c) == normal (string[0]))
          if (normal (c) == normal (string[0]))
            p++;
            p++;
        }
        }
    }
    }
}
}
 
 
/* Keep discarding input until we see the e7000 prompt.
/* Keep discarding input until we see the e7000 prompt.
 
 
   The convention for dealing with the prompt is that you
   The convention for dealing with the prompt is that you
   o give your command
   o give your command
   o *then* wait for the prompt.
   o *then* wait for the prompt.
 
 
   Thus the last thing that a procedure does with the serial line will
   Thus the last thing that a procedure does with the serial line will
   be an expect_prompt().  Exception: e7000_resume does not wait for
   be an expect_prompt().  Exception: e7000_resume does not wait for
   the prompt, because the terminal is being handed over to the
   the prompt, because the terminal is being handed over to the
   inferior.  However, the next thing which happens after that is a
   inferior.  However, the next thing which happens after that is a
   e7000_wait which does wait for the prompt.  Note that this includes
   e7000_wait which does wait for the prompt.  Note that this includes
   abnormal exit, e.g. error().  This is necessary to prevent getting
   abnormal exit, e.g. error().  This is necessary to prevent getting
   into states from which we can't recover.  */
   into states from which we can't recover.  */
 
 
static void
static void
expect_prompt ()
expect_prompt ()
{
{
  expect (":");
  expect (":");
}
}
 
 
static void
static void
expect_full_prompt ()
expect_full_prompt ()
{
{
  expect ("\r:");
  expect ("\r:");
}
}
 
 
static int
static int
convert_hex_digit (ch)
convert_hex_digit (ch)
     int ch;
     int ch;
{
{
  if (ch >= '0' && ch <= '9')
  if (ch >= '0' && ch <= '9')
    return ch - '0';
    return ch - '0';
  else if (ch >= 'A' && ch <= 'F')
  else if (ch >= 'A' && ch <= 'F')
    return ch - 'A' + 10;
    return ch - 'A' + 10;
  else if (ch >= 'a' && ch <= 'f')
  else if (ch >= 'a' && ch <= 'f')
    return ch - 'a' + 10;
    return ch - 'a' + 10;
  return -1;
  return -1;
}
}
 
 
static int
static int
get_hex (start)
get_hex (start)
     int *start;
     int *start;
{
{
  int value = convert_hex_digit (*start);
  int value = convert_hex_digit (*start);
  int try;
  int try;
 
 
  *start = readchar (timeout);
  *start = readchar (timeout);
  while ((try = convert_hex_digit (*start)) >= 0)
  while ((try = convert_hex_digit (*start)) >= 0)
    {
    {
      value <<= 4;
      value <<= 4;
      value += try;
      value += try;
      *start = readchar (timeout);
      *start = readchar (timeout);
    }
    }
  return value;
  return value;
}
}
 
 
#if 0
#if 0
/* Get N 32-bit words from remote, each preceded by a space, and put
/* Get N 32-bit words from remote, each preceded by a space, and put
   them in registers starting at REGNO.  */
   them in registers starting at REGNO.  */
 
 
static void
static void
get_hex_regs (n, regno)
get_hex_regs (n, regno)
     int n;
     int n;
     int regno;
     int regno;
{
{
  long val;
  long val;
  int i;
  int i;
 
 
  for (i = 0; i < n; i++)
  for (i = 0; i < n; i++)
    {
    {
      int j;
      int j;
 
 
      val = 0;
      val = 0;
      for (j = 0; j < 8; j++)
      for (j = 0; j < 8; j++)
        val = (val << 4) + get_hex_digit (j == 0);
        val = (val << 4) + get_hex_digit (j == 0);
      supply_register (regno++, (char *) &val);
      supply_register (regno++, (char *) &val);
    }
    }
}
}
#endif
#endif
 
 
/* This is called not only when we first attach, but also when the
/* This is called not only when we first attach, but also when the
   user types "run" after having attached.  */
   user types "run" after having attached.  */
 
 
static void
static void
e7000_create_inferior (execfile, args, env)
e7000_create_inferior (execfile, args, env)
     char *execfile;
     char *execfile;
     char *args;
     char *args;
     char **env;
     char **env;
{
{
  int entry_pt;
  int entry_pt;
 
 
  if (args && *args)
  if (args && *args)
    error ("Can't pass arguments to remote E7000DEBUG process");
    error ("Can't pass arguments to remote E7000DEBUG process");
 
 
  if (execfile == 0 || exec_bfd == 0)
  if (execfile == 0 || exec_bfd == 0)
    error ("No executable file specified");
    error ("No executable file specified");
 
 
  entry_pt = (int) bfd_get_start_address (exec_bfd);
  entry_pt = (int) bfd_get_start_address (exec_bfd);
 
 
#ifdef CREATE_INFERIOR_HOOK
#ifdef CREATE_INFERIOR_HOOK
  CREATE_INFERIOR_HOOK (0);      /* No process-ID */
  CREATE_INFERIOR_HOOK (0);      /* No process-ID */
#endif
#endif
 
 
  /* The "process" (board) is already stopped awaiting our commands, and
  /* The "process" (board) is already stopped awaiting our commands, and
     the program is already downloaded.  We just set its PC and go.  */
     the program is already downloaded.  We just set its PC and go.  */
 
 
  clear_proceed_status ();
  clear_proceed_status ();
 
 
  /* Tell wait_for_inferior that we've started a new process.  */
  /* Tell wait_for_inferior that we've started a new process.  */
  init_wait_for_inferior ();
  init_wait_for_inferior ();
 
 
  /* Set up the "saved terminal modes" of the inferior
  /* Set up the "saved terminal modes" of the inferior
     based on what modes we are starting it with.  */
     based on what modes we are starting it with.  */
  target_terminal_init ();
  target_terminal_init ();
 
 
  /* Install inferior's terminal modes.  */
  /* Install inferior's terminal modes.  */
  target_terminal_inferior ();
  target_terminal_inferior ();
 
 
  /* insert_step_breakpoint ();  FIXME, do we need this?  */
  /* insert_step_breakpoint ();  FIXME, do we need this?  */
  proceed ((CORE_ADDR) entry_pt, -1, 0); /* Let 'er rip... */
  proceed ((CORE_ADDR) entry_pt, -1, 0); /* Let 'er rip... */
}
}
 
 
/* Open a connection to a remote debugger.  NAME is the filename used
/* Open a connection to a remote debugger.  NAME is the filename used
   for communication.  */
   for communication.  */
 
 
static int baudrate = 9600;
static int baudrate = 9600;
static char dev_name[100];
static char dev_name[100];
 
 
static char *machine = "";
static char *machine = "";
static char *user = "";
static char *user = "";
static char *passwd = "";
static char *passwd = "";
static char *dir = "";
static char *dir = "";
 
 
/* Grab the next token and buy some space for it */
/* Grab the next token and buy some space for it */
 
 
static char *
static char *
next (ptr)
next (ptr)
     char **ptr;
     char **ptr;
{
{
  char *p = *ptr;
  char *p = *ptr;
  char *s;
  char *s;
  char *r;
  char *r;
  int l = 0;
  int l = 0;
 
 
  while (*p && *p == ' ')
  while (*p && *p == ' ')
    p++;
    p++;
  s = p;
  s = p;
  while (*p && (*p != ' ' && *p != '\t'))
  while (*p && (*p != ' ' && *p != '\t'))
    {
    {
      l++;
      l++;
      p++;
      p++;
    }
    }
  r = xmalloc (l + 1);
  r = xmalloc (l + 1);
  memcpy (r, s, l);
  memcpy (r, s, l);
  r[l] = 0;
  r[l] = 0;
  *ptr = p;
  *ptr = p;
  return r;
  return r;
}
}
 
 
static void
static void
e7000_login_command (args, from_tty)
e7000_login_command (args, from_tty)
     char *args;
     char *args;
     int from_tty;
     int from_tty;
{
{
  if (args)
  if (args)
    {
    {
      machine = next (&args);
      machine = next (&args);
      user = next (&args);
      user = next (&args);
      passwd = next (&args);
      passwd = next (&args);
      dir = next (&args);
      dir = next (&args);
      if (from_tty)
      if (from_tty)
        {
        {
          printf_unfiltered ("Set info to %s %s %s %s\n", machine, user, passwd, dir);
          printf_unfiltered ("Set info to %s %s %s %s\n", machine, user, passwd, dir);
        }
        }
    }
    }
  else
  else
    {
    {
      error ("Syntax is ftplogin <machine> <user> <passwd> <directory>");
      error ("Syntax is ftplogin <machine> <user> <passwd> <directory>");
    }
    }
}
}
 
 
/* Start an ftp transfer from the E7000 to a host */
/* Start an ftp transfer from the E7000 to a host */
 
 
static void
static void
e7000_ftp_command (args, from_tty)
e7000_ftp_command (args, from_tty)
     char *args;
     char *args;
     int from_tty;
     int from_tty;
{
{
  /* FIXME: arbitrary limit on machine names and such.  */
  /* FIXME: arbitrary limit on machine names and such.  */
  char buf[200];
  char buf[200];
 
 
  int oldtimeout = timeout;
  int oldtimeout = timeout;
  timeout = remote_timeout;
  timeout = remote_timeout;
 
 
  sprintf (buf, "ftp %s\r", machine);
  sprintf (buf, "ftp %s\r", machine);
  puts_e7000debug (buf);
  puts_e7000debug (buf);
  expect (" Username : ");
  expect (" Username : ");
  sprintf (buf, "%s\r", user);
  sprintf (buf, "%s\r", user);
  puts_e7000debug (buf);
  puts_e7000debug (buf);
  expect (" Password : ");
  expect (" Password : ");
  write_e7000 (passwd);
  write_e7000 (passwd);
  write_e7000 ("\r");
  write_e7000 ("\r");
  expect ("success\r");
  expect ("success\r");
  expect ("FTP>");
  expect ("FTP>");
  sprintf (buf, "cd %s\r", dir);
  sprintf (buf, "cd %s\r", dir);
  puts_e7000debug (buf);
  puts_e7000debug (buf);
  expect ("FTP>");
  expect ("FTP>");
  sprintf (buf, "ll 0;s:%s\r", args);
  sprintf (buf, "ll 0;s:%s\r", args);
  puts_e7000debug (buf);
  puts_e7000debug (buf);
  expect ("FTP>");
  expect ("FTP>");
  puts_e7000debug ("bye\r");
  puts_e7000debug ("bye\r");
  expect (":");
  expect (":");
  timeout = oldtimeout;
  timeout = oldtimeout;
}
}
 
 
static int
static int
e7000_parse_device (args, dev_name, baudrate)
e7000_parse_device (args, dev_name, baudrate)
     char *args;
     char *args;
     char *dev_name;
     char *dev_name;
     int baudrate;
     int baudrate;
{
{
  char junk[128];
  char junk[128];
  int n = 0;
  int n = 0;
  if (args && strcasecmp (args, "pc") == 0)
  if (args && strcasecmp (args, "pc") == 0)
    {
    {
      strcpy (dev_name, args);
      strcpy (dev_name, args);
      using_pc = 1;
      using_pc = 1;
    }
    }
  else
  else
    {
    {
      /* FIXME! temp hack to allow use with port master -
      /* FIXME! temp hack to allow use with port master -
         target tcp_remote <device> */
         target tcp_remote <device> */
      if (args && strncmp (args, "tcp", 10) == 0)
      if (args && strncmp (args, "tcp", 10) == 0)
        {
        {
          char com_type[128];
          char com_type[128];
          n = sscanf (args, " %s %s %d %s", com_type, dev_name, &baudrate, junk);
          n = sscanf (args, " %s %s %d %s", com_type, dev_name, &baudrate, junk);
          using_tcp_remote = 1;
          using_tcp_remote = 1;
          n--;
          n--;
        }
        }
      else if (args)
      else if (args)
        {
        {
          n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk);
          n = sscanf (args, " %s %d %s", dev_name, &baudrate, junk);
        }
        }
 
 
      if (n != 1 && n != 2)
      if (n != 1 && n != 2)
        {
        {
          error ("Bad arguments.  Usage:\ttarget e7000 <device> <speed>\n\
          error ("Bad arguments.  Usage:\ttarget e7000 <device> <speed>\n\
or \t\ttarget e7000 <host>[:<port>]\n\
or \t\ttarget e7000 <host>[:<port>]\n\
or \t\ttarget e7000 tcp_remote <host>[:<port>]\n\
or \t\ttarget e7000 tcp_remote <host>[:<port>]\n\
or \t\ttarget e7000 pc\n");
or \t\ttarget e7000 pc\n");
        }
        }
 
 
#if !defined(__GO32__) && !defined(_WIN32)
#if !defined(__GO32__) && !defined(_WIN32)
      /* FIXME!  test for ':' is ambiguous */
      /* FIXME!  test for ':' is ambiguous */
      if (n == 1 && strchr (dev_name, ':') == 0)
      if (n == 1 && strchr (dev_name, ':') == 0)
        {
        {
          /* Default to normal telnet port */
          /* Default to normal telnet port */
          /* serial_open will use this to determine tcp communication */
          /* serial_open will use this to determine tcp communication */
          strcat (dev_name, ":23");
          strcat (dev_name, ":23");
        }
        }
#endif
#endif
      if (!using_tcp_remote && strchr (dev_name, ':'))
      if (!using_tcp_remote && strchr (dev_name, ':'))
        using_tcp = 1;
        using_tcp = 1;
    }
    }
 
 
  return n;
  return n;
}
}
 
 
/* Stub for catch_errors.  */
/* Stub for catch_errors.  */
 
 
static int
static int
e7000_start_remote (dummy)
e7000_start_remote (dummy)
     char *dummy;
     char *dummy;
{
{
  int loop;
  int loop;
  int sync;
  int sync;
  int try;
  int try;
  int quit_trying;
  int quit_trying;
 
 
  immediate_quit = 1;           /* Allow user to interrupt it */
  immediate_quit = 1;           /* Allow user to interrupt it */
 
 
  /* Hello?  Are you there?  */
  /* Hello?  Are you there?  */
  sync = 0;
  sync = 0;
  loop = 0;
  loop = 0;
  try = 0;
  try = 0;
  quit_trying = 20;
  quit_trying = 20;
  putchar_e7000 (CTRLC);
  putchar_e7000 (CTRLC);
  while (!sync && ++try <= quit_trying)
  while (!sync && ++try <= quit_trying)
    {
    {
      int c;
      int c;
 
 
      printf_unfiltered ("[waiting for e7000...]\n");
      printf_unfiltered ("[waiting for e7000...]\n");
 
 
      write_e7000 ("\r");
      write_e7000 ("\r");
      c = readchar (1);
      c = readchar (1);
 
 
      /* FIXME!  this didn't seem right->  while (c != SERIAL_TIMEOUT)
      /* FIXME!  this didn't seem right->  while (c != SERIAL_TIMEOUT)
       * we get stuck in this loop ...
       * we get stuck in this loop ...
       * We may never timeout, and never sync up :-(
       * We may never timeout, and never sync up :-(
       */
       */
      while (!sync && c != -1)
      while (!sync && c != -1)
        {
        {
          /* Dont echo cr's */
          /* Dont echo cr's */
          if (c != '\r')
          if (c != '\r')
            {
            {
              putchar_unfiltered (c);
              putchar_unfiltered (c);
              gdb_flush (gdb_stdout);
              gdb_flush (gdb_stdout);
            }
            }
          /* Shouldn't we either break here, or check for sync in inner loop? */
          /* Shouldn't we either break here, or check for sync in inner loop? */
          if (c == ':')
          if (c == ':')
            sync = 1;
            sync = 1;
 
 
          if (loop++ == 20)
          if (loop++ == 20)
            {
            {
              putchar_e7000 (CTRLC);
              putchar_e7000 (CTRLC);
              loop = 0;
              loop = 0;
            }
            }
 
 
          QUIT;
          QUIT;
 
 
          if (quit_flag)
          if (quit_flag)
            {
            {
              putchar_e7000 (CTRLC);
              putchar_e7000 (CTRLC);
              /* Was-> quit_flag = 0; */
              /* Was-> quit_flag = 0; */
              c = -1;
              c = -1;
              quit_trying = try + 1;    /* we don't want to try anymore */
              quit_trying = try + 1;    /* we don't want to try anymore */
            }
            }
          else
          else
            {
            {
              c = readchar (1);
              c = readchar (1);
            }
            }
        }
        }
    }
    }
 
 
  if (!sync)
  if (!sync)
    {
    {
      fprintf_unfiltered (gdb_stderr, "Giving up after %d tries...\n", try);
      fprintf_unfiltered (gdb_stderr, "Giving up after %d tries...\n", try);
      error ("Unable to syncronize with target.\n");
      error ("Unable to syncronize with target.\n");
    }
    }
 
 
  puts_e7000debug ("\r");
  puts_e7000debug ("\r");
  expect_prompt ();
  expect_prompt ();
  puts_e7000debug ("b -\r");    /* Clear breakpoints */
  puts_e7000debug ("b -\r");    /* Clear breakpoints */
  expect_prompt ();
  expect_prompt ();
 
 
  immediate_quit = 0;
  immediate_quit = 0;
 
 
/* This is really the job of start_remote however, that makes an assumption
/* This is really the job of start_remote however, that makes an assumption
   that the target is about to print out a status message of some sort.  That
   that the target is about to print out a status message of some sort.  That
   doesn't happen here. */
   doesn't happen here. */
 
 
  flush_cached_frames ();
  flush_cached_frames ();
  registers_changed ();
  registers_changed ();
  stop_pc = read_pc ();
  stop_pc = read_pc ();
  set_current_frame (create_new_frame (read_fp (), stop_pc));
  set_current_frame (create_new_frame (read_fp (), stop_pc));
  select_frame (get_current_frame (), 0);
  select_frame (get_current_frame (), 0);
  print_stack_frame (selected_frame, -1, 1);
  print_stack_frame (selected_frame, -1, 1);
 
 
  return 1;
  return 1;
}
}
 
 
static void
static void
e7000_open (args, from_tty)
e7000_open (args, from_tty)
     char *args;
     char *args;
     int from_tty;
     int from_tty;
{
{
  int n;
  int n;
 
 
  target_preopen (from_tty);
  target_preopen (from_tty);
 
 
  n = e7000_parse_device (args, dev_name, baudrate);
  n = e7000_parse_device (args, dev_name, baudrate);
 
 
  push_target (&e7000_ops);
  push_target (&e7000_ops);
 
 
  e7000_desc = SERIAL_OPEN (dev_name);
  e7000_desc = SERIAL_OPEN (dev_name);
 
 
  if (!e7000_desc)
  if (!e7000_desc)
    perror_with_name (dev_name);
    perror_with_name (dev_name);
 
 
  SERIAL_SETBAUDRATE (e7000_desc, baudrate);
  SERIAL_SETBAUDRATE (e7000_desc, baudrate);
  SERIAL_RAW (e7000_desc);
  SERIAL_RAW (e7000_desc);
 
 
#ifdef GDB_TARGET_IS_H8300
#ifdef GDB_TARGET_IS_H8300
  h8300hmode = 1;
  h8300hmode = 1;
#endif
#endif
 
 
  /* Start the remote connection; if error (0), discard this target.
  /* Start the remote connection; if error (0), discard this target.
     In particular, if the user quits, be sure to discard it
     In particular, if the user quits, be sure to discard it
     (we'd be in an inconsistent state otherwise).  */
     (we'd be in an inconsistent state otherwise).  */
  if (!catch_errors (e7000_start_remote, (char *) 0,
  if (!catch_errors (e7000_start_remote, (char *) 0,
       "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
       "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
    if (from_tty)
    if (from_tty)
      printf_filtered ("Remote target %s connected to %s\n", target_shortname,
      printf_filtered ("Remote target %s connected to %s\n", target_shortname,
                       dev_name);
                       dev_name);
}
}
 
 
/* Close out all files and local state before this target loses control. */
/* Close out all files and local state before this target loses control. */
 
 
static void
static void
e7000_close (quitting)
e7000_close (quitting)
     int quitting;
     int quitting;
{
{
  if (e7000_desc)
  if (e7000_desc)
    {
    {
      SERIAL_CLOSE (e7000_desc);
      SERIAL_CLOSE (e7000_desc);
      e7000_desc = 0;
      e7000_desc = 0;
    }
    }
}
}
 
 
/* Terminate the open connection to the remote debugger.  Use this
/* Terminate the open connection to the remote debugger.  Use this
   when you want to detach and do something else with your gdb.  */
   when you want to detach and do something else with your gdb.  */
 
 
static void
static void
e7000_detach (from_tty)
e7000_detach (from_tty)
     int from_tty;
     int from_tty;
{
{
  pop_target ();                /* calls e7000_close to do the real work */
  pop_target ();                /* calls e7000_close to do the real work */
  if (from_tty)
  if (from_tty)
    printf_unfiltered ("Ending remote %s debugging\n", target_shortname);
    printf_unfiltered ("Ending remote %s debugging\n", target_shortname);
}
}
 
 
/* Tell the remote machine to resume.  */
/* Tell the remote machine to resume.  */
 
 
static void
static void
e7000_resume (pid, step, sig)
e7000_resume (pid, step, sig)
     int pid, step, sig;
     int pid, step, sig;
{
{
  if (step)
  if (step)
    puts_e7000debug ("S\r");
    puts_e7000debug ("S\r");
  else
  else
    puts_e7000debug ("G\r");
    puts_e7000debug ("G\r");
}
}
 
 
/* Read the remote registers into the block REGS.
/* Read the remote registers into the block REGS.
 
 
   For the H8/300 a register dump looks like:
   For the H8/300 a register dump looks like:
 
 
   PC=00021A  CCR=80:I*******
   PC=00021A  CCR=80:I*******
   ER0 - ER3  0000000A 0000002E 0000002E 00000000
   ER0 - ER3  0000000A 0000002E 0000002E 00000000
   ER4 - ER7  00000000 00000000 00000000 00FFEFF6
   ER4 - ER7  00000000 00000000 00000000 00FFEFF6
   000218           MOV.B     R1L,R2L
   000218           MOV.B     R1L,R2L
   STEP NORMAL END or
   STEP NORMAL END or
   BREAK POINT
   BREAK POINT
 */
 */
 
 
#ifdef GDB_TARGET_IS_H8300
#ifdef GDB_TARGET_IS_H8300
 
 
char *want_h8300h = "PC=%p CCR=%c\n\
char *want_h8300h = "PC=%p CCR=%c\n\
 ER0 - ER3  %0 %1 %2 %3\n\
 ER0 - ER3  %0 %1 %2 %3\n\
 ER4 - ER7  %4 %5 %6 %7\n";
 ER4 - ER7  %4 %5 %6 %7\n";
 
 
char *want_nopc_h8300h = "%p CCR=%c\n\
char *want_nopc_h8300h = "%p CCR=%c\n\
 ER0 - ER3  %0 %1 %2 %3\n\
 ER0 - ER3  %0 %1 %2 %3\n\
 ER4 - ER7  %4 %5 %6 %7";
 ER4 - ER7  %4 %5 %6 %7";
 
 
char *want_h8300s = "PC=%p CCR=%c\n\
char *want_h8300s = "PC=%p CCR=%c\n\
 MACH=\n\
 MACH=\n\
 ER0 - ER3  %0 %1 %2 %3\n\
 ER0 - ER3  %0 %1 %2 %3\n\
 ER4 - ER7  %4 %5 %6 %7\n";
 ER4 - ER7  %4 %5 %6 %7\n";
 
 
char *want_nopc_h8300s = "%p CCR=%c EXR=%9\n\
char *want_nopc_h8300s = "%p CCR=%c EXR=%9\n\
 ER0 - ER3  %0 %1 %2 %3\n\
 ER0 - ER3  %0 %1 %2 %3\n\
 ER4 - ER7  %4 %5 %6 %7";
 ER4 - ER7  %4 %5 %6 %7";
 
 
#endif
#endif
 
 
#ifdef GDB_TARGET_IS_SH
#ifdef GDB_TARGET_IS_SH
 
 
char *want = "PC=%16 SR=%22\n\
char *want = "PC=%16 SR=%22\n\
PR=%17 GBR=%18 VBR=%19\n\
PR=%17 GBR=%18 VBR=%19\n\
MACH=%20 MACL=%21\n\
MACH=%20 MACL=%21\n\
R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n";
R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n";
 
 
char *want_nopc = "%16 SR=%22\n\
char *want_nopc = "%16 SR=%22\n\
 PR=%17 GBR=%18 VBR=%19\n\
 PR=%17 GBR=%18 VBR=%19\n\
 MACH=%20 MACL=%21\n\
 MACH=%20 MACL=%21\n\
 R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
 R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
 R8-15 %8 %9 %10 %11 %12 %13 %14 %15";
 R8-15 %8 %9 %10 %11 %12 %13 %14 %15";
 
 
char *want_sh3 = "PC=%16 SR=%22\n\
char *want_sh3 = "PC=%16 SR=%22\n\
PR=%17 GBR=%18 VBR=%19\n\
PR=%17 GBR=%18 VBR=%19\n\
MACH=%20 MACL=%21 SSR=%23 SPC=%24\n\
MACH=%20 MACL=%21 SSR=%23 SPC=%24\n\
R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
R4_BANK1-R7_BANK1 %37 %38 %39 %40";
R4_BANK1-R7_BANK1 %37 %38 %39 %40";
 
 
char *want_sh3_nopc = "%16 SR=%22\n\
char *want_sh3_nopc = "%16 SR=%22\n\
 PR=%17 GBR=%18 VBR=%19\n\
 PR=%17 GBR=%18 VBR=%19\n\
 MACH=%20 MACL=%21 SSR=%22 SPC=%23\n\
 MACH=%20 MACL=%21 SSR=%22 SPC=%23\n\
 R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
 R0-7  %0 %1 %2 %3 %4 %5 %6 %7\n\
 R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
 R8-15 %8 %9 %10 %11 %12 %13 %14 %15\n\
 R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
 R0_BANK0-R3_BANK0 %25 %26 %27 %28\n\
 R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
 R4_BANK0-R7_BANK0 %29 %30 %31 %32\n\
 R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
 R0_BANK1-R3_BANK1 %33 %34 %35 %36\n\
 R4_BANK1-R7_BANK1 %37 %38 %39 %40";
 R4_BANK1-R7_BANK1 %37 %38 %39 %40";
 
 
#endif
#endif
 
 
static int
static int
gch ()
gch ()
{
{
  return readchar (timeout);
  return readchar (timeout);
}
}
 
 
static unsigned int
static unsigned int
gbyte ()
gbyte ()
{
{
  int high = convert_hex_digit (gch ());
  int high = convert_hex_digit (gch ());
  int low = convert_hex_digit (gch ());
  int low = convert_hex_digit (gch ());
 
 
  return (high << 4) + low;
  return (high << 4) + low;
}
}
 
 
void
void
fetch_regs_from_dump (nextchar, want)
fetch_regs_from_dump (nextchar, want)
     int (*nextchar) ();
     int (*nextchar) ();
     char *want;
     char *want;
{
{
  int regno;
  int regno;
  char buf[MAX_REGISTER_RAW_SIZE];
  char buf[MAX_REGISTER_RAW_SIZE];
 
 
  int thischar = nextchar ();
  int thischar = nextchar ();
 
 
  while (*want)
  while (*want)
    {
    {
      switch (*want)
      switch (*want)
        {
        {
        case '\n':
        case '\n':
          /* Skip to end of line and then eat all new line type stuff */
          /* Skip to end of line and then eat all new line type stuff */
          while (thischar != '\n' && thischar != '\r')
          while (thischar != '\n' && thischar != '\r')
            thischar = nextchar ();
            thischar = nextchar ();
          while (thischar == '\n' || thischar == '\r')
          while (thischar == '\n' || thischar == '\r')
            thischar = nextchar ();
            thischar = nextchar ();
          want++;
          want++;
          break;
          break;
 
 
        case ' ':
        case ' ':
          while (thischar == ' '
          while (thischar == ' '
                 || thischar == '\t'
                 || thischar == '\t'
                 || thischar == '\r'
                 || thischar == '\r'
                 || thischar == '\n')
                 || thischar == '\n')
            thischar = nextchar ();
            thischar = nextchar ();
          want++;
          want++;
          break;
          break;
 
 
        default:
        default:
          if (*want == thischar)
          if (*want == thischar)
            {
            {
              want++;
              want++;
              if (*want)
              if (*want)
                thischar = nextchar ();
                thischar = nextchar ();
 
 
            }
            }
          else if (thischar == ' ' || thischar == '\n' || thischar == '\r')
          else if (thischar == ' ' || thischar == '\n' || thischar == '\r')
            {
            {
              thischar = nextchar ();
              thischar = nextchar ();
            }
            }
          else
          else
            {
            {
              error ("out of sync in fetch registers wanted <%s>, got <%c 0x%x>",
              error ("out of sync in fetch registers wanted <%s>, got <%c 0x%x>",
                     want, thischar, thischar);
                     want, thischar, thischar);
            }
            }
 
 
          break;
          break;
        case '%':
        case '%':
          /* Got a register command */
          /* Got a register command */
          want++;
          want++;
          switch (*want)
          switch (*want)
            {
            {
#ifdef PC_REGNUM
#ifdef PC_REGNUM
            case 'p':
            case 'p':
              regno = PC_REGNUM;
              regno = PC_REGNUM;
              want++;
              want++;
              break;
              break;
#endif
#endif
#ifdef CCR_REGNUM
#ifdef CCR_REGNUM
            case 'c':
            case 'c':
              regno = CCR_REGNUM;
              regno = CCR_REGNUM;
              want++;
              want++;
              break;
              break;
#endif
#endif
#ifdef SP_REGNUM
#ifdef SP_REGNUM
            case 's':
            case 's':
              regno = SP_REGNUM;
              regno = SP_REGNUM;
              want++;
              want++;
              break;
              break;
#endif
#endif
#ifdef FP_REGNUM
#ifdef FP_REGNUM
            case 'f':
            case 'f':
              regno = FP_REGNUM;
              regno = FP_REGNUM;
              want++;
              want++;
              break;
              break;
#endif
#endif
 
 
            default:
            default:
              if (isdigit (want[0]))
              if (isdigit (want[0]))
                {
                {
                  if (isdigit (want[1]))
                  if (isdigit (want[1]))
                    {
                    {
                      regno = (want[0] - '0') * 10 + want[1] - '0';
                      regno = (want[0] - '0') * 10 + want[1] - '0';
                      want += 2;
                      want += 2;
                    }
                    }
                  else
                  else
                    {
                    {
                      regno = want[0] - '0';
                      regno = want[0] - '0';
                      want++;
                      want++;
                    }
                    }
                }
                }
 
 
              else
              else
                abort ();
                abort ();
            }
            }
          store_signed_integer (buf,
          store_signed_integer (buf,
                                REGISTER_RAW_SIZE (regno),
                                REGISTER_RAW_SIZE (regno),
                                (LONGEST) get_hex (&thischar, nextchar));
                                (LONGEST) get_hex (&thischar, nextchar));
          supply_register (regno, buf);
          supply_register (regno, buf);
          break;
          break;
        }
        }
    }
    }
}
}
 
 
static void
static void
e7000_fetch_registers ()
e7000_fetch_registers ()
{
{
  int regno;
  int regno;
  char *wanted;
  char *wanted;
 
 
  puts_e7000debug ("R\r");
  puts_e7000debug ("R\r");
 
 
#ifdef GDB_TARGET_IS_SH
#ifdef GDB_TARGET_IS_SH
  wanted = want;
  wanted = want;
  if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
  if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
    switch (TARGET_ARCHITECTURE->mach)
    switch (TARGET_ARCHITECTURE->mach)
      {
      {
      case bfd_mach_sh3:
      case bfd_mach_sh3:
      case bfd_mach_sh3e:
      case bfd_mach_sh3e:
      case bfd_mach_sh4:
      case bfd_mach_sh4:
        wanted = want_sh3;
        wanted = want_sh3;
      }
      }
#else
#else
  if (h8300smode)
  if (h8300smode)
    wanted = want_h8300s;
    wanted = want_h8300s;
  else
  else
    wanted = want_h8300h;
    wanted = want_h8300h;
#endif
#endif
  fetch_regs_from_dump (gch, wanted);
  fetch_regs_from_dump (gch, wanted);
 
 
  /* And supply the extra ones the simulator uses */
  /* And supply the extra ones the simulator uses */
  for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
  for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
    {
    {
      int buf = 0;
      int buf = 0;
 
 
      supply_register (regno, (char *) (&buf));
      supply_register (regno, (char *) (&buf));
    }
    }
}
}
 
 
/* Fetch register REGNO, or all registers if REGNO is -1.  Returns
/* Fetch register REGNO, or all registers if REGNO is -1.  Returns
   errno value.  */
   errno value.  */
 
 
static void
static void
e7000_fetch_register (regno)
e7000_fetch_register (regno)
     int regno;
     int regno;
{
{
  e7000_fetch_registers ();
  e7000_fetch_registers ();
}
}
 
 
/* Store the remote registers from the contents of the block REGS.  */
/* Store the remote registers from the contents of the block REGS.  */
 
 
static void
static void
e7000_store_registers ()
e7000_store_registers ()
{
{
  int regno;
  int regno;
 
 
  for (regno = 0; regno < NUM_REALREGS; regno++)
  for (regno = 0; regno < NUM_REALREGS; regno++)
    e7000_store_register (regno);
    e7000_store_register (regno);
 
 
  registers_changed ();
  registers_changed ();
}
}
 
 
/* Store register REGNO, or all if REGNO == 0.  Return errno value.  */
/* Store register REGNO, or all if REGNO == 0.  Return errno value.  */
 
 
static void
static void
e7000_store_register (regno)
e7000_store_register (regno)
     int regno;
     int regno;
{
{
  char buf[200];
  char buf[200];
 
 
  if (regno == -1)
  if (regno == -1)
    {
    {
      e7000_store_registers ();
      e7000_store_registers ();
      return;
      return;
    }
    }
 
 
#ifdef GDB_TARGET_IS_H8300
#ifdef GDB_TARGET_IS_H8300
  if (regno <= 7)
  if (regno <= 7)
    {
    {
      sprintf (buf, ".ER%d %x\r", regno, read_register (regno));
      sprintf (buf, ".ER%d %x\r", regno, read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
    }
    }
  else if (regno == PC_REGNUM)
  else if (regno == PC_REGNUM)
    {
    {
      sprintf (buf, ".PC %x\r", read_register (regno));
      sprintf (buf, ".PC %x\r", read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
    }
    }
  else if (regno == CCR_REGNUM)
  else if (regno == CCR_REGNUM)
    {
    {
      sprintf (buf, ".CCR %x\r", read_register (regno));
      sprintf (buf, ".CCR %x\r", read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
    }
    }
#endif /* GDB_TARGET_IS_H8300 */
#endif /* GDB_TARGET_IS_H8300 */
 
 
#ifdef  GDB_TARGET_IS_SH
#ifdef  GDB_TARGET_IS_SH
  switch (regno)
  switch (regno)
    {
    {
    default:
    default:
      sprintf (buf, ".R%d %x\r", regno, read_register (regno));
      sprintf (buf, ".R%d %x\r", regno, read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
      break;
      break;
 
 
    case PC_REGNUM:
    case PC_REGNUM:
      sprintf (buf, ".PC %x\r", read_register (regno));
      sprintf (buf, ".PC %x\r", read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
      break;
      break;
 
 
    case SR_REGNUM:
    case SR_REGNUM:
      sprintf (buf, ".SR %x\r", read_register (regno));
      sprintf (buf, ".SR %x\r", read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
      break;
      break;
 
 
    case PR_REGNUM:
    case PR_REGNUM:
      sprintf (buf, ".PR %x\r", read_register (regno));
      sprintf (buf, ".PR %x\r", read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
      break;
      break;
 
 
    case GBR_REGNUM:
    case GBR_REGNUM:
      sprintf (buf, ".GBR %x\r", read_register (regno));
      sprintf (buf, ".GBR %x\r", read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
      break;
      break;
 
 
    case VBR_REGNUM:
    case VBR_REGNUM:
      sprintf (buf, ".VBR %x\r", read_register (regno));
      sprintf (buf, ".VBR %x\r", read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
      break;
      break;
 
 
    case MACH_REGNUM:
    case MACH_REGNUM:
      sprintf (buf, ".MACH %x\r", read_register (regno));
      sprintf (buf, ".MACH %x\r", read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
      break;
      break;
 
 
    case MACL_REGNUM:
    case MACL_REGNUM:
      sprintf (buf, ".MACL %x\r", read_register (regno));
      sprintf (buf, ".MACL %x\r", read_register (regno));
      puts_e7000debug (buf);
      puts_e7000debug (buf);
      break;
      break;
    }
    }
 
 
#endif /* GDB_TARGET_IS_SH */
#endif /* GDB_TARGET_IS_SH */
 
 
  expect_prompt ();
  expect_prompt ();
}
}
 
 
/* Get ready to modify the registers array.  On machines which store
/* Get ready to modify the registers array.  On machines which store
   individual registers, this doesn't need to do anything.  On machines
   individual registers, this doesn't need to do anything.  On machines
   which store all the registers in one fell swoop, this makes sure
   which store all the registers in one fell swoop, this makes sure
   that registers contains all the registers from the program being
   that registers contains all the registers from the program being
   debugged.  */
   debugged.  */
 
 
static void
static void
e7000_prepare_to_store ()
e7000_prepare_to_store ()
{
{
  /* Do nothing, since we can store individual regs */
  /* Do nothing, since we can store individual regs */
}
}
 
 
static void
static void
e7000_files_info ()
e7000_files_info ()
{
{
  printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baudrate);
  printf_unfiltered ("\tAttached to %s at %d baud.\n", dev_name, baudrate);
}
}
 
 
static int
static int
stickbyte (where, what)
stickbyte (where, what)
     char *where;
     char *where;
     unsigned int what;
     unsigned int what;
{
{
  static CONST char digs[] = "0123456789ABCDEF";
  static CONST char digs[] = "0123456789ABCDEF";
 
 
  where[0] = digs[(what >> 4) & 0xf];
  where[0] = digs[(what >> 4) & 0xf];
  where[1] = digs[(what & 0xf) & 0xf];
  where[1] = digs[(what & 0xf) & 0xf];
 
 
  return what;
  return what;
}
}
 
 
/* Write a small ammount of memory. */
/* Write a small ammount of memory. */
 
 
static int
static int
write_small (memaddr, myaddr, len)
write_small (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     CORE_ADDR memaddr;
     unsigned char *myaddr;
     unsigned char *myaddr;
     int len;
     int len;
{
{
  int i;
  int i;
  char buf[200];
  char buf[200];
 
 
  for (i = 0; i < len; i++)
  for (i = 0; i < len; i++)
    {
    {
      if (((memaddr + i) & 3) == 0 && (i + 3 < len))
      if (((memaddr + i) & 3) == 0 && (i + 3 < len))
        {
        {
          /* Can be done with a long word */
          /* Can be done with a long word */
          sprintf (buf, "m %x %x%02x%02x%02x;l\r",
          sprintf (buf, "m %x %x%02x%02x%02x;l\r",
                   memaddr + i,
                   memaddr + i,
                   myaddr[i], myaddr[i + 1], myaddr[i + 2], myaddr[i + 3]);
                   myaddr[i], myaddr[i + 1], myaddr[i + 2], myaddr[i + 3]);
          puts_e7000debug (buf);
          puts_e7000debug (buf);
          i += 3;
          i += 3;
        }
        }
      else
      else
        {
        {
          sprintf (buf, "m %x %x\r", memaddr + i, myaddr[i]);
          sprintf (buf, "m %x %x\r", memaddr + i, myaddr[i]);
          puts_e7000debug (buf);
          puts_e7000debug (buf);
        }
        }
    }
    }
 
 
  expect_prompt ();
  expect_prompt ();
 
 
  return len;
  return len;
}
}
 
 
/* Write a large ammount of memory, this only works with the serial
/* Write a large ammount of memory, this only works with the serial
   mode enabled.  Command is sent as
   mode enabled.  Command is sent as
 
 
   il ;s:s\r     ->
   il ;s:s\r     ->
   <- il ;s:s\r
   <- il ;s:s\r
   <-   ENQ
   <-   ENQ
   ACK          ->
   ACK          ->
   <- LO s\r
   <- LO s\r
   Srecords...
   Srecords...
   ^Z           ->
   ^Z           ->
   <-   ENQ
   <-   ENQ
   ACK          ->
   ACK          ->
   <-   :
   <-   :
 */
 */
 
 
static int
static int
write_large (memaddr, myaddr, len)
write_large (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     CORE_ADDR memaddr;
     unsigned char *myaddr;
     unsigned char *myaddr;
     int len;
     int len;
{
{
  int i;
  int i;
#define maxstride  128
#define maxstride  128
  int stride;
  int stride;
 
 
  puts_e7000debug ("IL ;S:FK\r");
  puts_e7000debug ("IL ;S:FK\r");
  expect (ENQSTRING);
  expect (ENQSTRING);
  putchar_e7000 (ACK);
  putchar_e7000 (ACK);
  expect ("LO FK\r");
  expect ("LO FK\r");
 
 
  for (i = 0; i < len; i += stride)
  for (i = 0; i < len; i += stride)
    {
    {
      char compose[maxstride * 2 + 50];
      char compose[maxstride * 2 + 50];
      int address = i + memaddr;
      int address = i + memaddr;
      int j;
      int j;
      int check_sum;
      int check_sum;
      int where = 0;
      int where = 0;
      int alen;
      int alen;
 
 
      stride = len - i;
      stride = len - i;
      if (stride > maxstride)
      if (stride > maxstride)
        stride = maxstride;
        stride = maxstride;
 
 
      compose[where++] = 'S';
      compose[where++] = 'S';
      check_sum = 0;
      check_sum = 0;
      if (address >= 0xffffff)
      if (address >= 0xffffff)
        alen = 4;
        alen = 4;
      else if (address >= 0xffff)
      else if (address >= 0xffff)
        alen = 3;
        alen = 3;
      else
      else
        alen = 2;
        alen = 2;
      /* Insert type. */
      /* Insert type. */
      compose[where++] = alen - 1 + '0';
      compose[where++] = alen - 1 + '0';
      /* Insert length. */
      /* Insert length. */
      check_sum += stickbyte (compose + where, alen + stride + 1);
      check_sum += stickbyte (compose + where, alen + stride + 1);
      where += 2;
      where += 2;
      while (alen > 0)
      while (alen > 0)
        {
        {
          alen--;
          alen--;
          check_sum += stickbyte (compose + where, address >> (8 * (alen)));
          check_sum += stickbyte (compose + where, address >> (8 * (alen)));
          where += 2;
          where += 2;
        }
        }
 
 
      for (j = 0; j < stride; j++)
      for (j = 0; j < stride; j++)
        {
        {
          check_sum += stickbyte (compose + where, myaddr[i + j]);
          check_sum += stickbyte (compose + where, myaddr[i + j]);
          where += 2;
          where += 2;
        }
        }
      stickbyte (compose + where, ~check_sum);
      stickbyte (compose + where, ~check_sum);
      where += 2;
      where += 2;
      compose[where++] = '\r';
      compose[where++] = '\r';
      compose[where++] = '\n';
      compose[where++] = '\n';
      compose[where++] = 0;
      compose[where++] = 0;
 
 
      SERIAL_WRITE (e7000_desc, compose, where);
      SERIAL_WRITE (e7000_desc, compose, where);
      j = readchar (0);
      j = readchar (0);
      if (j == -1)
      if (j == -1)
        {
        {
          /* This is ok - nothing there */
          /* This is ok - nothing there */
        }
        }
      else if (j == ENQ)
      else if (j == ENQ)
        {
        {
          /* Hmm, it's trying to tell us something */
          /* Hmm, it's trying to tell us something */
          expect (":");
          expect (":");
          error ("Error writing memory");
          error ("Error writing memory");
        }
        }
      else
      else
        {
        {
          printf_unfiltered ("@%d}@", j);
          printf_unfiltered ("@%d}@", j);
          while ((j = readchar (0)) > 0)
          while ((j = readchar (0)) > 0)
            {
            {
              printf_unfiltered ("@{%d}@", j);
              printf_unfiltered ("@{%d}@", j);
            }
            }
        }
        }
    }
    }
 
 
  /* Send the trailer record */
  /* Send the trailer record */
  write_e7000 ("S70500000000FA\r");
  write_e7000 ("S70500000000FA\r");
  putchar_e7000 (CTRLZ);
  putchar_e7000 (CTRLZ);
  expect (ENQSTRING);
  expect (ENQSTRING);
  putchar_e7000 (ACK);
  putchar_e7000 (ACK);
  expect (":");
  expect (":");
 
 
  return len;
  return len;
}
}
 
 
/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's
   memory at MEMADDR.  Returns length moved.
   memory at MEMADDR.  Returns length moved.
 
 
   Can't use the Srecord load over ethernet, so don't use fast method
   Can't use the Srecord load over ethernet, so don't use fast method
   then.  */
   then.  */
 
 
static int
static int
e7000_write_inferior_memory (memaddr, myaddr, len)
e7000_write_inferior_memory (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     CORE_ADDR memaddr;
     unsigned char *myaddr;
     unsigned char *myaddr;
     int len;
     int len;
{
{
  if (len < 16 || using_tcp || using_pc)
  if (len < 16 || using_tcp || using_pc)
    return write_small (memaddr, myaddr, len);
    return write_small (memaddr, myaddr, len);
  else
  else
    return write_large (memaddr, myaddr, len);
    return write_large (memaddr, myaddr, len);
}
}
 
 
/* Read LEN bytes from inferior memory at MEMADDR.  Put the result
/* Read LEN bytes from inferior memory at MEMADDR.  Put the result
   at debugger address MYADDR.  Returns length moved.
   at debugger address MYADDR.  Returns length moved.
 
 
   Small transactions we send
   Small transactions we send
   m <addr>;l
   m <addr>;l
   and receive
   and receive
   00000000 12345678 ?
   00000000 12345678 ?
 */
 */
 
 
static int
static int
e7000_read_inferior_memory (memaddr, myaddr, len)
e7000_read_inferior_memory (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     CORE_ADDR memaddr;
     unsigned char *myaddr;
     unsigned char *myaddr;
     int len;
     int len;
{
{
  int count;
  int count;
  int c;
  int c;
  int i;
  int i;
  char buf[200];
  char buf[200];
  /* Starting address of this pass.  */
  /* Starting address of this pass.  */
 
 
/*  printf("READ INF %x %x %d\n", memaddr, myaddr, len); */
/*  printf("READ INF %x %x %d\n", memaddr, myaddr, len); */
  if (((memaddr - 1) + len) < memaddr)
  if (((memaddr - 1) + len) < memaddr)
    {
    {
      errno = EIO;
      errno = EIO;
      return 0;
      return 0;
    }
    }
 
 
  sprintf (buf, "m %x;l\r", memaddr);
  sprintf (buf, "m %x;l\r", memaddr);
  puts_e7000debug (buf);
  puts_e7000debug (buf);
 
 
  for (count = 0; count < len; count += 4)
  for (count = 0; count < len; count += 4)
    {
    {
      /* Suck away the address */
      /* Suck away the address */
      c = gch ();
      c = gch ();
      while (c != ' ')
      while (c != ' ')
        c = gch ();
        c = gch ();
      c = gch ();
      c = gch ();
      if (c == '*')
      if (c == '*')
        {                       /* Some kind of error */
        {                       /* Some kind of error */
          puts_e7000debug (".\r");      /* Some errors leave us in memory input mode */
          puts_e7000debug (".\r");      /* Some errors leave us in memory input mode */
          expect_full_prompt ();
          expect_full_prompt ();
          return -1;
          return -1;
        }
        }
      while (c != ' ')
      while (c != ' ')
        c = gch ();
        c = gch ();
 
 
      /* Now read in the data */
      /* Now read in the data */
      for (i = 0; i < 4; i++)
      for (i = 0; i < 4; i++)
        {
        {
          int b = gbyte ();
          int b = gbyte ();
          if (count + i < len)
          if (count + i < len)
            {
            {
              myaddr[count + i] = b;
              myaddr[count + i] = b;
            }
            }
        }
        }
 
 
      /* Skip the trailing ? and send a . to end and a cr for more */
      /* Skip the trailing ? and send a . to end and a cr for more */
      gch ();
      gch ();
      gch ();
      gch ();
      if (count + 4 >= len)
      if (count + 4 >= len)
        puts_e7000debug (".\r");
        puts_e7000debug (".\r");
      else
      else
        puts_e7000debug ("\r");
        puts_e7000debug ("\r");
 
 
    }
    }
  expect_prompt ();
  expect_prompt ();
  return len;
  return len;
}
}
 
 
 
 
 
 
/*
/*
   For large transfers we used to send
   For large transfers we used to send
 
 
 
 
   d <addr> <endaddr>\r
   d <addr> <endaddr>\r
 
 
   and receive
   and receive
   <ADDRESS>           <    D   A   T   A    >               <   ASCII CODE   >
   <ADDRESS>           <    D   A   T   A    >               <   ASCII CODE   >
   00000000 5F FD FD FF DF 7F DF FF  01 00 01 00 02 00 08 04  "_..............."
   00000000 5F FD FD FF DF 7F DF FF  01 00 01 00 02 00 08 04  "_..............."
   00000010 FF D7 FF 7F D7 F1 7F FF  00 05 00 00 08 00 40 00  "..............@."
   00000010 FF D7 FF 7F D7 F1 7F FF  00 05 00 00 08 00 40 00  "..............@."
   00000020 7F FD FF F7 7F FF FF F7  00 00 00 00 00 00 00 00  "................"
   00000020 7F FD FF F7 7F FF FF F7  00 00 00 00 00 00 00 00  "................"
 
 
   A cost in chars for each transaction of 80 + 5*n-bytes.
   A cost in chars for each transaction of 80 + 5*n-bytes.
 
 
   Large transactions could be done with the srecord load code, but
   Large transactions could be done with the srecord load code, but
   there is a pause for a second before dumping starts, which slows the
   there is a pause for a second before dumping starts, which slows the
   average rate down!
   average rate down!
 */
 */
 
 
static int
static int
e7000_read_inferior_memory_large (memaddr, myaddr, len)
e7000_read_inferior_memory_large (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     CORE_ADDR memaddr;
     unsigned char *myaddr;
     unsigned char *myaddr;
     int len;
     int len;
{
{
  int count;
  int count;
  int c;
  int c;
  char buf[200];
  char buf[200];
 
 
  /* Starting address of this pass.  */
  /* Starting address of this pass.  */
 
 
  if (((memaddr - 1) + len) < memaddr)
  if (((memaddr - 1) + len) < memaddr)
    {
    {
      errno = EIO;
      errno = EIO;
      return 0;
      return 0;
    }
    }
 
 
  sprintf (buf, "d %x %x\r", memaddr, memaddr + len - 1);
  sprintf (buf, "d %x %x\r", memaddr, memaddr + len - 1);
  puts_e7000debug (buf);
  puts_e7000debug (buf);
 
 
  count = 0;
  count = 0;
  c = gch ();
  c = gch ();
 
 
  /* skip down to the first ">" */
  /* skip down to the first ">" */
  while (c != '>')
  while (c != '>')
    c = gch ();
    c = gch ();
  /* now skip to the end of that line */
  /* now skip to the end of that line */
  while (c != '\r')
  while (c != '\r')
    c = gch ();
    c = gch ();
  c = gch ();
  c = gch ();
 
 
  while (count < len)
  while (count < len)
    {
    {
      /* get rid of any white space before the address */
      /* get rid of any white space before the address */
      while (c <= ' ')
      while (c <= ' ')
        c = gch ();
        c = gch ();
 
 
      /* Skip the address */
      /* Skip the address */
      get_hex (&c);
      get_hex (&c);
 
 
      /* read in the bytes on the line */
      /* read in the bytes on the line */
      while (c != '"' && count < len)
      while (c != '"' && count < len)
        {
        {
          if (c == ' ')
          if (c == ' ')
            c = gch ();
            c = gch ();
          else
          else
            {
            {
              myaddr[count++] = get_hex (&c);
              myaddr[count++] = get_hex (&c);
            }
            }
        }
        }
      /* throw out the rest of the line */
      /* throw out the rest of the line */
      while (c != '\r')
      while (c != '\r')
        c = gch ();
        c = gch ();
    }
    }
 
 
  /* wait for the ":" prompt */
  /* wait for the ":" prompt */
  while (c != ':')
  while (c != ':')
    c = gch ();
    c = gch ();
 
 
  return len;
  return len;
}
}
 
 
#if 0
#if 0
 
 
static int
static int
fast_but_for_the_pause_e7000_read_inferior_memory (memaddr, myaddr, len)
fast_but_for_the_pause_e7000_read_inferior_memory (memaddr, myaddr, len)
     CORE_ADDR memaddr;
     CORE_ADDR memaddr;
     char *myaddr;
     char *myaddr;
     int len;
     int len;
{
{
  int loop;
  int loop;
  int c;
  int c;
  char buf[200];
  char buf[200];
 
 
  if (((memaddr - 1) + len) < memaddr)
  if (((memaddr - 1) + len) < memaddr)
    {
    {
      errno = EIO;
      errno = EIO;
      return 0;
      return 0;
    }
    }
 
 
  sprintf (buf, "is %x@%x:s\r", memaddr, len);
  sprintf (buf, "is %x@%x:s\r", memaddr, len);
  puts_e7000debug (buf);
  puts_e7000debug (buf);
  gch ();
  gch ();
  c = gch ();
  c = gch ();
  if (c != ENQ)
  if (c != ENQ)
    {
    {
      /* Got an error */
      /* Got an error */
      error ("Memory read error");
      error ("Memory read error");
    }
    }
  putchar_e7000 (ACK);
  putchar_e7000 (ACK);
  expect ("SV s");
  expect ("SV s");
  loop = 1;
  loop = 1;
  while (loop)
  while (loop)
    {
    {
      int type;
      int type;
      int length;
      int length;
      int addr;
      int addr;
      int i;
      int i;
 
 
      c = gch ();
      c = gch ();
      switch (c)
      switch (c)
        {
        {
        case ENQ:               /* ENQ, at the end */
        case ENQ:               /* ENQ, at the end */
          loop = 0;
          loop = 0;
          break;
          break;
        case 'S':
        case 'S':
          /* Start of an Srecord */
          /* Start of an Srecord */
          type = gch ();
          type = gch ();
          length = gbyte ();
          length = gbyte ();
          switch (type)
          switch (type)
            {
            {
            case '7':           /* Termination record, ignore */
            case '7':           /* Termination record, ignore */
            case '0':
            case '0':
            case '8':
            case '8':
            case '9':
            case '9':
              /* Header record - ignore it */
              /* Header record - ignore it */
              while (length--)
              while (length--)
                {
                {
                  gbyte ();
                  gbyte ();
                }
                }
              break;
              break;
            case '1':
            case '1':
            case '2':
            case '2':
            case '3':
            case '3':
              {
              {
                int alen;
                int alen;
 
 
                alen = type - '0' + 1;
                alen = type - '0' + 1;
                addr = 0;
                addr = 0;
                while (alen--)
                while (alen--)
                  {
                  {
                    addr = (addr << 8) + gbyte ();
                    addr = (addr << 8) + gbyte ();
                    length--;
                    length--;
                  }
                  }
 
 
                for (i = 0; i < length - 1; i++)
                for (i = 0; i < length - 1; i++)
                  myaddr[i + addr - memaddr] = gbyte ();
                  myaddr[i + addr - memaddr] = gbyte ();
 
 
                gbyte ();       /* Ignore checksum */
                gbyte ();       /* Ignore checksum */
              }
              }
            }
            }
        }
        }
    }
    }
 
 
  putchar_e7000 (ACK);
  putchar_e7000 (ACK);
  expect ("TOP ADDRESS =");
  expect ("TOP ADDRESS =");
  expect ("END ADDRESS =");
  expect ("END ADDRESS =");
  expect (":");
  expect (":");
 
 
  return len;
  return len;
}
}
 
 
#endif
#endif
 
 
static int
static int
e7000_xfer_inferior_memory (memaddr, myaddr, len, write, target)
e7000_xfer_inferior_memory (memaddr, myaddr, len, write, target)
     CORE_ADDR memaddr;
     CORE_ADDR memaddr;
     unsigned char *myaddr;
     unsigned char *myaddr;
     int len;
     int len;
     int write;
     int write;
     struct target_ops *target; /* ignored */
     struct target_ops *target; /* ignored */
{
{
  if (write)
  if (write)
    return e7000_write_inferior_memory (memaddr, myaddr, len);
    return e7000_write_inferior_memory (memaddr, myaddr, len);
  else if (len < 16)
  else if (len < 16)
    return e7000_read_inferior_memory (memaddr, myaddr, len);
    return e7000_read_inferior_memory (memaddr, myaddr, len);
  else
  else
    return e7000_read_inferior_memory_large (memaddr, myaddr, len);
    return e7000_read_inferior_memory_large (memaddr, myaddr, len);
}
}
 
 
static void
static void
e7000_kill (args, from_tty)
e7000_kill (args, from_tty)
     char *args;
     char *args;
     int from_tty;
     int from_tty;
{
{
}
}
 
 
static void
static void
e7000_load (args, from_tty)
e7000_load (args, from_tty)
     char *args;
     char *args;
     int from_tty;
     int from_tty;
{
{
  struct cleanup *old_chain;
  struct cleanup *old_chain;
  asection *section;
  asection *section;
  bfd *pbfd;
  bfd *pbfd;
  bfd_vma entry;
  bfd_vma entry;
#define WRITESIZE 0x1000
#define WRITESIZE 0x1000
  char buf[2 + 4 + 4 + WRITESIZE];      /* `DT' + <addr> + <len> + <data> */
  char buf[2 + 4 + 4 + WRITESIZE];      /* `DT' + <addr> + <len> + <data> */
  char *filename;
  char *filename;
  int quiet;
  int quiet;
  int nostart;
  int nostart;
  time_t start_time, end_time;  /* Start and end times of download */
  time_t start_time, end_time;  /* Start and end times of download */
  unsigned long data_count;     /* Number of bytes transferred to memory */
  unsigned long data_count;     /* Number of bytes transferred to memory */
  int oldtimeout = timeout;
  int oldtimeout = timeout;
 
 
  timeout = remote_timeout;
  timeout = remote_timeout;
 
 
 
 
  /* FIXME! change test to test for type of download */
  /* FIXME! change test to test for type of download */
  if (!using_tcp)
  if (!using_tcp)
    {
    {
      generic_load (args, from_tty);
      generic_load (args, from_tty);
      return;
      return;
    }
    }
 
 
  /* for direct tcp connections, we can do a fast binary download */
  /* for direct tcp connections, we can do a fast binary download */
  buf[0] = 'D';
  buf[0] = 'D';
  buf[1] = 'T';
  buf[1] = 'T';
  quiet = 0;
  quiet = 0;
  nostart = 0;
  nostart = 0;
  filename = NULL;
  filename = NULL;
 
 
  while (*args != '\000')
  while (*args != '\000')
    {
    {
      char *arg;
      char *arg;
 
 
      while (isspace (*args))
      while (isspace (*args))
        args++;
        args++;
 
 
      arg = args;
      arg = args;
 
 
      while ((*args != '\000') && !isspace (*args))
      while ((*args != '\000') && !isspace (*args))
        args++;
        args++;
 
 
      if (*args != '\000')
      if (*args != '\000')
        *args++ = '\000';
        *args++ = '\000';
 
 
      if (*arg != '-')
      if (*arg != '-')
        filename = arg;
        filename = arg;
      else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
      else if (strncmp (arg, "-quiet", strlen (arg)) == 0)
        quiet = 1;
        quiet = 1;
      else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
      else if (strncmp (arg, "-nostart", strlen (arg)) == 0)
        nostart = 1;
        nostart = 1;
      else
      else
        error ("unknown option `%s'", arg);
        error ("unknown option `%s'", arg);
    }
    }
 
 
  if (!filename)
  if (!filename)
    filename = get_exec_file (1);
    filename = get_exec_file (1);
 
 
  pbfd = bfd_openr (filename, gnutarget);
  pbfd = bfd_openr (filename, gnutarget);
  if (pbfd == NULL)
  if (pbfd == NULL)
    {
    {
      perror_with_name (filename);
      perror_with_name (filename);
      return;
      return;
    }
    }
  old_chain = make_cleanup ((make_cleanup_func) bfd_close, pbfd);
  old_chain = make_cleanup ((make_cleanup_func) bfd_close, pbfd);
 
 
  if (!bfd_check_format (pbfd, bfd_object))
  if (!bfd_check_format (pbfd, bfd_object))
    error ("\"%s\" is not an object file: %s", filename,
    error ("\"%s\" is not an object file: %s", filename,
           bfd_errmsg (bfd_get_error ()));
           bfd_errmsg (bfd_get_error ()));
 
 
  start_time = time (NULL);
  start_time = time (NULL);
  data_count = 0;
  data_count = 0;
 
 
  puts_e7000debug ("mw\r");
  puts_e7000debug ("mw\r");
 
 
  expect ("\nOK");
  expect ("\nOK");
 
 
  for (section = pbfd->sections; section; section = section->next)
  for (section = pbfd->sections; section; section = section->next)
    {
    {
      if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
      if (bfd_get_section_flags (pbfd, section) & SEC_LOAD)
        {
        {
          bfd_vma section_address;
          bfd_vma section_address;
          bfd_size_type section_size;
          bfd_size_type section_size;
          file_ptr fptr;
          file_ptr fptr;
 
 
          section_address = bfd_get_section_vma (pbfd, section);
          section_address = bfd_get_section_vma (pbfd, section);
          section_size = bfd_get_section_size_before_reloc (section);
          section_size = bfd_get_section_size_before_reloc (section);
 
 
          if (!quiet)
          if (!quiet)
            printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n",
            printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n",
                             bfd_get_section_name (pbfd, section),
                             bfd_get_section_name (pbfd, section),
                             section_address,
                             section_address,
                             section_size);
                             section_size);
 
 
          fptr = 0;
          fptr = 0;
 
 
          data_count += section_size;
          data_count += section_size;
 
 
          while (section_size > 0)
          while (section_size > 0)
            {
            {
              int count;
              int count;
              static char inds[] = "|/-\\";
              static char inds[] = "|/-\\";
              static int k = 0;
              static int k = 0;
 
 
              QUIT;
              QUIT;
 
 
              count = min (section_size, WRITESIZE);
              count = min (section_size, WRITESIZE);
 
 
              buf[2] = section_address >> 24;
              buf[2] = section_address >> 24;
              buf[3] = section_address >> 16;
              buf[3] = section_address >> 16;
              buf[4] = section_address >> 8;
              buf[4] = section_address >> 8;
              buf[5] = section_address;
              buf[5] = section_address;
 
 
              buf[6] = count >> 24;
              buf[6] = count >> 24;
              buf[7] = count >> 16;
              buf[7] = count >> 16;
              buf[8] = count >> 8;
              buf[8] = count >> 8;
              buf[9] = count;
              buf[9] = count;
 
 
              bfd_get_section_contents (pbfd, section, buf + 10, fptr, count);
              bfd_get_section_contents (pbfd, section, buf + 10, fptr, count);
 
 
              if (SERIAL_WRITE (e7000_desc, buf, count + 10))
              if (SERIAL_WRITE (e7000_desc, buf, count + 10))
                fprintf_unfiltered (gdb_stderr,
                fprintf_unfiltered (gdb_stderr,
                                    "e7000_load: SERIAL_WRITE failed: %s\n",
                                    "e7000_load: SERIAL_WRITE failed: %s\n",
                                    safe_strerror (errno));
                                    safe_strerror (errno));
 
 
              expect ("OK");
              expect ("OK");
 
 
              if (!quiet)
              if (!quiet)
                {
                {
                  printf_unfiltered ("\r%c", inds[k++ % 4]);
                  printf_unfiltered ("\r%c", inds[k++ % 4]);
                  gdb_flush (gdb_stdout);
                  gdb_flush (gdb_stdout);
                }
                }
 
 
              section_address += count;
              section_address += count;
              fptr += count;
              fptr += count;
              section_size -= count;
              section_size -= count;
            }
            }
        }
        }
    }
    }
 
 
  write_e7000 ("ED");
  write_e7000 ("ED");
 
 
  expect_prompt ();
  expect_prompt ();
 
 
  end_time = time (NULL);
  end_time = time (NULL);
 
 
/* Finally, make the PC point at the start address */
/* Finally, make the PC point at the start address */
 
 
  if (exec_bfd)
  if (exec_bfd)
    write_pc (bfd_get_start_address (exec_bfd));
    write_pc (bfd_get_start_address (exec_bfd));
 
 
  inferior_pid = 0;              /* No process now */
  inferior_pid = 0;              /* No process now */
 
 
/* This is necessary because many things were based on the PC at the time that
/* This is necessary because many things were based on the PC at the time that
   we attached to the monitor, which is no longer valid now that we have loaded
   we attached to the monitor, which is no longer valid now that we have loaded
   new code (and just changed the PC).  Another way to do this might be to call
   new code (and just changed the PC).  Another way to do this might be to call
   normal_stop, except that the stack may not be valid, and things would get
   normal_stop, except that the stack may not be valid, and things would get
   horribly confused... */
   horribly confused... */
 
 
  clear_symtab_users ();
  clear_symtab_users ();
 
 
  if (!nostart)
  if (!nostart)
    {
    {
      entry = bfd_get_start_address (pbfd);
      entry = bfd_get_start_address (pbfd);
 
 
      if (!quiet)
      if (!quiet)
        printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry);
        printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry);
 
 
/*      start_routine (entry); */
/*      start_routine (entry); */
    }
    }
 
 
  report_transfer_performance (data_count, start_time, end_time);
  report_transfer_performance (data_count, start_time, end_time);
 
 
  do_cleanups (old_chain);
  do_cleanups (old_chain);
  timeout = oldtimeout;
  timeout = oldtimeout;
}
}
 
 
/* Clean up when a program exits.
/* Clean up when a program exits.
 
 
   The program actually lives on in the remote processor's RAM, and may be
   The program actually lives on in the remote processor's RAM, and may be
   run again without a download.  Don't leave it full of breakpoint
   run again without a download.  Don't leave it full of breakpoint
   instructions.  */
   instructions.  */
 
 
static void
static void
e7000_mourn_inferior ()
e7000_mourn_inferior ()
{
{
  remove_breakpoints ();
  remove_breakpoints ();
  unpush_target (&e7000_ops);
  unpush_target (&e7000_ops);
  generic_mourn_inferior ();    /* Do all the proper things now */
  generic_mourn_inferior ();    /* Do all the proper things now */
}
}
 
 
#define MAX_BREAKPOINTS 200
#define MAX_BREAKPOINTS 200
#ifdef  HARD_BREAKPOINTS
#ifdef  HARD_BREAKPOINTS
#define MAX_E7000DEBUG_BREAKPOINTS (BC_BREAKPOINTS ? 5 :  MAX_BREAKPOINTS)
#define MAX_E7000DEBUG_BREAKPOINTS (BC_BREAKPOINTS ? 5 :  MAX_BREAKPOINTS)
#else
#else
#define MAX_E7000DEBUG_BREAKPOINTS MAX_BREAKPOINTS
#define MAX_E7000DEBUG_BREAKPOINTS MAX_BREAKPOINTS
#endif
#endif
 
 
/* Since we can change to soft breakpoints dynamically, we must define
/* Since we can change to soft breakpoints dynamically, we must define
   more than enough.  Was breakaddr[MAX_E7000DEBUG_BREAKPOINTS]. */
   more than enough.  Was breakaddr[MAX_E7000DEBUG_BREAKPOINTS]. */
static CORE_ADDR breakaddr[MAX_BREAKPOINTS] =
static CORE_ADDR breakaddr[MAX_BREAKPOINTS] =
{0};
{0};
 
 
static int
static int
e7000_insert_breakpoint (addr, shadow)
e7000_insert_breakpoint (addr, shadow)
     CORE_ADDR addr;
     CORE_ADDR addr;
     unsigned char *shadow;
     unsigned char *shadow;
{
{
  int i;
  int i;
  char buf[200];
  char buf[200];
#if 0
#if 0
  static char nop[2] = NOP;
  static char nop[2] = NOP;
#endif
#endif
 
 
  for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++)
  for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++)
    if (breakaddr[i] == 0)
    if (breakaddr[i] == 0)
      {
      {
        breakaddr[i] = addr;
        breakaddr[i] = addr;
        /* Save old contents, and insert a nop in the space */
        /* Save old contents, and insert a nop in the space */
#ifdef HARD_BREAKPOINTS
#ifdef HARD_BREAKPOINTS
        if (BC_BREAKPOINTS)
        if (BC_BREAKPOINTS)
          {
          {
            sprintf (buf, "BC%d A=%x\r", i + 1, addr);
            sprintf (buf, "BC%d A=%x\r", i + 1, addr);
            puts_e7000debug (buf);
            puts_e7000debug (buf);
          }
          }
        else
        else
          {
          {
            sprintf (buf, "B %x\r", addr);
            sprintf (buf, "B %x\r", addr);
            puts_e7000debug (buf);
            puts_e7000debug (buf);
          }
          }
#else
#else
#if 0
#if 0
        e7000_read_inferior_memory (addr, shadow, 2);
        e7000_read_inferior_memory (addr, shadow, 2);
        e7000_write_inferior_memory (addr, nop, 2);
        e7000_write_inferior_memory (addr, nop, 2);
#endif
#endif
 
 
        sprintf (buf, "B %x\r", addr);
        sprintf (buf, "B %x\r", addr);
        puts_e7000debug (buf);
        puts_e7000debug (buf);
#endif
#endif
        expect_prompt ();
        expect_prompt ();
        return 0;
        return 0;
      }
      }
 
 
  error ("Too many breakpoints ( > %d) for the E7000\n",
  error ("Too many breakpoints ( > %d) for the E7000\n",
         MAX_E7000DEBUG_BREAKPOINTS);
         MAX_E7000DEBUG_BREAKPOINTS);
  return 1;
  return 1;
}
}
 
 
static int
static int
e7000_remove_breakpoint (addr, shadow)
e7000_remove_breakpoint (addr, shadow)
     CORE_ADDR addr;
     CORE_ADDR addr;
     unsigned char *shadow;
     unsigned char *shadow;
{
{
  int i;
  int i;
  char buf[200];
  char buf[200];
 
 
  for (i = 0; i < MAX_E7000DEBUG_BREAKPOINTS; i++)
  for (i = 0; i < MAX_E7000DEBUG_BREAKPOINTS; i++)
    if (breakaddr[i] == addr)
    if (breakaddr[i] == addr)
      {
      {
        breakaddr[i] = 0;
        breakaddr[i] = 0;
#ifdef HARD_BREAKPOINTS
#ifdef HARD_BREAKPOINTS
        if (BC_BREAKPOINTS)
        if (BC_BREAKPOINTS)
          {
          {
            sprintf (buf, "BC%d - \r", i + 1);
            sprintf (buf, "BC%d - \r", i + 1);
            puts_e7000debug (buf);
            puts_e7000debug (buf);
          }
          }
        else
        else
          {
          {
            sprintf (buf, "B - %x\r", addr);
            sprintf (buf, "B - %x\r", addr);
            puts_e7000debug (buf);
            puts_e7000debug (buf);
          }
          }
        expect_prompt ();
        expect_prompt ();
#else
#else
        sprintf (buf, "B - %x\r", addr);
        sprintf (buf, "B - %x\r", addr);
        puts_e7000debug (buf);
        puts_e7000debug (buf);
        expect_prompt ();
        expect_prompt ();
 
 
#if 0
#if 0
        /* Replace the insn under the break */
        /* Replace the insn under the break */
        e7000_write_inferior_memory (addr, shadow, 2);
        e7000_write_inferior_memory (addr, shadow, 2);
#endif
#endif
#endif
#endif
 
 
        return 0;
        return 0;
      }
      }
 
 
  warning ("Can't find breakpoint associated with 0x%x\n", addr);
  warning ("Can't find breakpoint associated with 0x%x\n", addr);
  return 1;
  return 1;
}
}
 
 
/* Put a command string, in args, out to STDBUG.  Output from STDBUG
/* Put a command string, in args, out to STDBUG.  Output from STDBUG
   is placed on the users terminal until the prompt is seen. */
   is placed on the users terminal until the prompt is seen. */
 
 
static void
static void
e7000_command (args, fromtty)
e7000_command (args, fromtty)
     char *args;
     char *args;
     int fromtty;
     int fromtty;
{
{
  /* FIXME: arbitrary limit on length of args.  */
  /* FIXME: arbitrary limit on length of args.  */
  char buf[200];
  char buf[200];
 
 
  echo = 0;
  echo = 0;
 
 
  if (!e7000_desc)
  if (!e7000_desc)
    error ("e7000 target not open.");
    error ("e7000 target not open.");
  if (!args)
  if (!args)
    {
    {
      puts_e7000debug ("\r");
      puts_e7000debug ("\r");
    }
    }
  else
  else
    {
    {
      sprintf (buf, "%s\r", args);
      sprintf (buf, "%s\r", args);
      puts_e7000debug (buf);
      puts_e7000debug (buf);
    }
    }
 
 
  echo++;
  echo++;
  ctrl_c = 2;
  ctrl_c = 2;
  expect_full_prompt ();
  expect_full_prompt ();
  echo--;
  echo--;
  ctrl_c = 0;
  ctrl_c = 0;
  printf_unfiltered ("\n");
  printf_unfiltered ("\n");
 
 
  /* Who knows what the command did... */
  /* Who knows what the command did... */
  registers_changed ();
  registers_changed ();
}
}
 
 
 
 
static void
static void
e7000_drain_command (args, fromtty)
e7000_drain_command (args, fromtty)
     char *args;
     char *args;
     int fromtty;
     int fromtty;
 
 
{
{
  int c;
  int c;
 
 
  puts_e7000debug ("end\r");
  puts_e7000debug ("end\r");
  putchar_e7000 (CTRLC);
  putchar_e7000 (CTRLC);
 
 
  while ((c = readchar (1) != -1))
  while ((c = readchar (1) != -1))
    {
    {
      if (quit_flag)
      if (quit_flag)
        {
        {
          putchar_e7000 (CTRLC);
          putchar_e7000 (CTRLC);
          quit_flag = 0;
          quit_flag = 0;
        }
        }
      if (c > ' ' && c < 127)
      if (c > ' ' && c < 127)
        printf_unfiltered ("%c", c & 0xff);
        printf_unfiltered ("%c", c & 0xff);
      else
      else
        printf_unfiltered ("<%x>", c & 0xff);
        printf_unfiltered ("<%x>", c & 0xff);
    }
    }
}
}
 
 
#define NITEMS 7
#define NITEMS 7
 
 
static int
static int
why_stop ()
why_stop ()
{
{
  static char *strings[NITEMS] =
  static char *strings[NITEMS] =
  {
  {
    "STEP NORMAL",
    "STEP NORMAL",
    "BREAK POINT",
    "BREAK POINT",
    "BREAK KEY",
    "BREAK KEY",
    "BREAK CONDI",
    "BREAK CONDI",
    "CYCLE ACCESS",
    "CYCLE ACCESS",
    "ILLEGAL INSTRUCTION",
    "ILLEGAL INSTRUCTION",
    "WRITE PROTECT",
    "WRITE PROTECT",
  };
  };
  char *p[NITEMS];
  char *p[NITEMS];
  int c;
  int c;
  int i;
  int i;
 
 
  for (i = 0; i < NITEMS; ++i)
  for (i = 0; i < NITEMS; ++i)
    p[i] = strings[i];
    p[i] = strings[i];
 
 
  c = gch ();
  c = gch ();
  while (1)
  while (1)
    {
    {
      for (i = 0; i < NITEMS; i++)
      for (i = 0; i < NITEMS; i++)
        {
        {
          if (c == *(p[i]))
          if (c == *(p[i]))
            {
            {
              p[i]++;
              p[i]++;
              if (*(p[i]) == 0)
              if (*(p[i]) == 0)
                {
                {
                  /* found one of the choices */
                  /* found one of the choices */
                  return i;
                  return i;
                }
                }
            }
            }
          else
          else
            p[i] = strings[i];
            p[i] = strings[i];
        }
        }
 
 
      c = gch ();
      c = gch ();
    }
    }
}
}
 
 
/* Suck characters, if a string match, then return the strings index
/* Suck characters, if a string match, then return the strings index
   otherwise echo them.  */
   otherwise echo them.  */
 
 
int
int
expect_n (strings)
expect_n (strings)
     char **strings;
     char **strings;
{
{
  char *(ptr[10]);
  char *(ptr[10]);
  int n;
  int n;
  int c;
  int c;
  char saveaway[100];
  char saveaway[100];
  char *buffer = saveaway;
  char *buffer = saveaway;
  /* Count number of expect strings  */
  /* Count number of expect strings  */
 
 
  for (n = 0; strings[n]; n++)
  for (n = 0; strings[n]; n++)
    {
    {
      ptr[n] = strings[n];
      ptr[n] = strings[n];
    }
    }
 
 
  while (1)
  while (1)
    {
    {
      int i;
      int i;
      int gotone = 0;
      int gotone = 0;
 
 
      c = readchar (1);
      c = readchar (1);
      if (c == -1)
      if (c == -1)
        {
        {
          printf_unfiltered ("[waiting for e7000...]\n");
          printf_unfiltered ("[waiting for e7000...]\n");
        }
        }
#ifdef __GO32__
#ifdef __GO32__
      if (kbhit ())
      if (kbhit ())
        {
        {
          int k = getkey ();
          int k = getkey ();
 
 
          if (k == 1)
          if (k == 1)
            quit_flag = 1;
            quit_flag = 1;
        }
        }
#endif
#endif
      if (quit_flag)
      if (quit_flag)
        {
        {
          putchar_e7000 (CTRLC);        /* interrupt the running program */
          putchar_e7000 (CTRLC);        /* interrupt the running program */
          quit_flag = 0;
          quit_flag = 0;
        }
        }
 
 
      for (i = 0; i < n; i++)
      for (i = 0; i < n; i++)
        {
        {
          if (c == ptr[i][0])
          if (c == ptr[i][0])
            {
            {
              ptr[i]++;
              ptr[i]++;
              if (ptr[i][0] == 0)
              if (ptr[i][0] == 0)
                {
                {
                  /* Gone all the way */
                  /* Gone all the way */
                  return i;
                  return i;
                }
                }
              gotone = 1;
              gotone = 1;
            }
            }
          else
          else
            {
            {
              ptr[i] = strings[i];
              ptr[i] = strings[i];
            }
            }
        }
        }
 
 
      if (gotone)
      if (gotone)
        {
        {
          /* Save it up incase we find that there was no match */
          /* Save it up incase we find that there was no match */
          *buffer++ = c;
          *buffer++ = c;
        }
        }
      else
      else
        {
        {
          if (buffer != saveaway)
          if (buffer != saveaway)
            {
            {
              *buffer++ = 0;
              *buffer++ = 0;
              printf_unfiltered ("%s", buffer);
              printf_unfiltered ("%s", buffer);
              buffer = saveaway;
              buffer = saveaway;
            }
            }
          if (c != -1)
          if (c != -1)
            {
            {
              putchar_unfiltered (c);
              putchar_unfiltered (c);
              gdb_flush (gdb_stdout);
              gdb_flush (gdb_stdout);
            }
            }
        }
        }
    }
    }
}
}
 
 
/* We subtract two from the pc here rather than use
/* We subtract two from the pc here rather than use
   DECR_PC_AFTER_BREAK since the e7000 doesn't always add two to the
   DECR_PC_AFTER_BREAK since the e7000 doesn't always add two to the
   pc, and the simulators never do. */
   pc, and the simulators never do. */
 
 
static void
static void
sub2_from_pc ()
sub2_from_pc ()
{
{
  char buf[4];
  char buf[4];
  char buf2[200];
  char buf2[200];
 
 
  store_signed_integer (buf,
  store_signed_integer (buf,
                        REGISTER_RAW_SIZE (PC_REGNUM),
                        REGISTER_RAW_SIZE (PC_REGNUM),
                        read_register (PC_REGNUM) - 2);
                        read_register (PC_REGNUM) - 2);
  supply_register (PC_REGNUM, buf);
  supply_register (PC_REGNUM, buf);
  sprintf (buf2, ".PC %x\r", read_register (PC_REGNUM));
  sprintf (buf2, ".PC %x\r", read_register (PC_REGNUM));
  puts_e7000debug (buf2);
  puts_e7000debug (buf2);
}
}
 
 
#define WAS_SLEEP 0
#define WAS_SLEEP 0
#define WAS_INT 1
#define WAS_INT 1
#define WAS_RUNNING 2
#define WAS_RUNNING 2
#define WAS_OTHER 3
#define WAS_OTHER 3
 
 
static char *estrings[] =
static char *estrings[] =
{
{
  "** SLEEP",
  "** SLEEP",
  "BREAK !",
  "BREAK !",
  "** PC",
  "** PC",
  "PC",
  "PC",
  NULL
  NULL
};
};
 
 
/* Wait until the remote machine stops, then return, storing status in
/* Wait until the remote machine stops, then return, storing status in
   STATUS just as `wait' would.  */
   STATUS just as `wait' would.  */
 
 
static int
static int
e7000_wait (pid, status)
e7000_wait (pid, status)
     int pid;
     int pid;
     struct target_waitstatus *status;
     struct target_waitstatus *status;
{
{
  int stop_reason;
  int stop_reason;
  int regno;
  int regno;
  int running_count = 0;
  int running_count = 0;
  int had_sleep = 0;
  int had_sleep = 0;
  int loop = 1;
  int loop = 1;
  char *wanted_nopc;
  char *wanted_nopc;
 
 
  /* Then echo chars until PC= string seen */
  /* Then echo chars until PC= string seen */
  gch ();                       /* Drop cr */
  gch ();                       /* Drop cr */
  gch ();                       /* and space */
  gch ();                       /* and space */
 
 
  while (loop)
  while (loop)
    {
    {
      switch (expect_n (estrings))
      switch (expect_n (estrings))
        {
        {
        case WAS_OTHER:
        case WAS_OTHER:
          /* how did this happen ? */
          /* how did this happen ? */
          loop = 0;
          loop = 0;
          break;
          break;
        case WAS_SLEEP:
        case WAS_SLEEP:
          had_sleep = 1;
          had_sleep = 1;
          putchar_e7000 (CTRLC);
          putchar_e7000 (CTRLC);
          loop = 0;
          loop = 0;
          break;
          break;
        case WAS_INT:
        case WAS_INT:
          loop = 0;
          loop = 0;
          break;
          break;
        case WAS_RUNNING:
        case WAS_RUNNING:
          running_count++;
          running_count++;
          if (running_count == 20)
          if (running_count == 20)
            {
            {
              printf_unfiltered ("[running...]\n");
              printf_unfiltered ("[running...]\n");
              running_count = 0;
              running_count = 0;
            }
            }
          break;
          break;
        default:
        default:
          /* error? */
          /* error? */
          break;
          break;
        }
        }
    }
    }
 
 
  /* Skip till the PC= */
  /* Skip till the PC= */
  expect ("=");
  expect ("=");
 
 
#ifdef GDB_TARGET_IS_SH
#ifdef GDB_TARGET_IS_SH
  wanted_nopc = want_nopc;
  wanted_nopc = want_nopc;
  if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
  if (TARGET_ARCHITECTURE->arch == bfd_arch_sh)
    switch (TARGET_ARCHITECTURE->mach)
    switch (TARGET_ARCHITECTURE->mach)
      {
      {
      case bfd_mach_sh3:
      case bfd_mach_sh3:
      case bfd_mach_sh3e:
      case bfd_mach_sh3e:
      case bfd_mach_sh4:
      case bfd_mach_sh4:
        wanted_nopc = want_sh3_nopc;
        wanted_nopc = want_sh3_nopc;
      }
      }
#else
#else
  if (h8300smode)
  if (h8300smode)
    wanted_nopc = want_nopc_h8300s;
    wanted_nopc = want_nopc_h8300s;
  else
  else
    wanted_nopc = want_nopc_h8300h;
    wanted_nopc = want_nopc_h8300h;
#endif
#endif
  fetch_regs_from_dump (gch, wanted_nopc);
  fetch_regs_from_dump (gch, wanted_nopc);
 
 
  /* And supply the extra ones the simulator uses */
  /* And supply the extra ones the simulator uses */
  for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
  for (regno = NUM_REALREGS; regno < NUM_REGS; regno++)
    {
    {
      int buf = 0;
      int buf = 0;
      supply_register (regno, (char *) &buf);
      supply_register (regno, (char *) &buf);
    }
    }
 
 
  stop_reason = why_stop ();
  stop_reason = why_stop ();
  expect_full_prompt ();
  expect_full_prompt ();
 
 
  status->kind = TARGET_WAITKIND_STOPPED;
  status->kind = TARGET_WAITKIND_STOPPED;
  status->value.sig = TARGET_SIGNAL_TRAP;
  status->value.sig = TARGET_SIGNAL_TRAP;
 
 
  switch (stop_reason)
  switch (stop_reason)
    {
    {
    case 1:                     /* Breakpoint */
    case 1:                     /* Breakpoint */
      write_pc (read_pc ());    /* PC is always off by 2 for breakpoints */
      write_pc (read_pc ());    /* PC is always off by 2 for breakpoints */
      status->value.sig = TARGET_SIGNAL_TRAP;
      status->value.sig = TARGET_SIGNAL_TRAP;
      break;
      break;
    case 0:                      /* Single step */
    case 0:                      /* Single step */
      status->value.sig = TARGET_SIGNAL_TRAP;
      status->value.sig = TARGET_SIGNAL_TRAP;
      break;
      break;
    case 2:                     /* Interrupt */
    case 2:                     /* Interrupt */
      if (had_sleep)
      if (had_sleep)
        {
        {
          status->value.sig = TARGET_SIGNAL_TRAP;
          status->value.sig = TARGET_SIGNAL_TRAP;
          sub2_from_pc ();
          sub2_from_pc ();
        }
        }
      else
      else
        {
        {
          status->value.sig = TARGET_SIGNAL_INT;
          status->value.sig = TARGET_SIGNAL_INT;
        }
        }
      break;
      break;
    case 3:
    case 3:
      break;
      break;
    case 4:
    case 4:
      printf_unfiltered ("a cycle address error?\n");
      printf_unfiltered ("a cycle address error?\n");
      status->value.sig = TARGET_SIGNAL_UNKNOWN;
      status->value.sig = TARGET_SIGNAL_UNKNOWN;
      break;
      break;
    case 5:
    case 5:
      status->value.sig = TARGET_SIGNAL_ILL;
      status->value.sig = TARGET_SIGNAL_ILL;
      break;
      break;
    case 6:
    case 6:
      status->value.sig = TARGET_SIGNAL_SEGV;
      status->value.sig = TARGET_SIGNAL_SEGV;
      break;
      break;
    case 7:                     /* Anything else (NITEMS + 1) */
    case 7:                     /* Anything else (NITEMS + 1) */
      printf_unfiltered ("a write protect error?\n");
      printf_unfiltered ("a write protect error?\n");
      status->value.sig = TARGET_SIGNAL_UNKNOWN;
      status->value.sig = TARGET_SIGNAL_UNKNOWN;
      break;
      break;
    default:
    default:
      /* Get the user's attention - this should never happen. */
      /* Get the user's attention - this should never happen. */
      abort ();
      abort ();
    }
    }
 
 
  return 0;
  return 0;
}
}
 
 
/* Stop the running program.  */
/* Stop the running program.  */
 
 
static void
static void
e7000_stop ()
e7000_stop ()
{
{
  /* Sending a ^C is supposed to stop the running program.  */
  /* Sending a ^C is supposed to stop the running program.  */
  putchar_e7000 (CTRLC);
  putchar_e7000 (CTRLC);
}
}
 
 
/* Define the target subroutine names. */
/* Define the target subroutine names. */
 
 
struct target_ops e7000_ops;
struct target_ops e7000_ops;
 
 
static void
static void
init_e7000_ops (void)
init_e7000_ops (void)
{
{
  e7000_ops.to_shortname = "e7000";
  e7000_ops.to_shortname = "e7000";
  e7000_ops.to_longname = "Remote Hitachi e7000 target";
  e7000_ops.to_longname = "Remote Hitachi e7000 target";
  e7000_ops.to_doc = "Use a remote Hitachi e7000 ICE connected by a serial line;\n\
  e7000_ops.to_doc = "Use a remote Hitachi e7000 ICE connected by a serial line;\n\
or a network connection.\n\
or a network connection.\n\
Arguments are the name of the device for the serial line,\n\
Arguments are the name of the device for the serial line,\n\
the speed to connect at in bits per second.\n\
the speed to connect at in bits per second.\n\
eg\n\
eg\n\
target e7000 /dev/ttya 9600\n\
target e7000 /dev/ttya 9600\n\
target e7000 foobar";
target e7000 foobar";
  e7000_ops.to_open = e7000_open;
  e7000_ops.to_open = e7000_open;
  e7000_ops.to_close = e7000_close;
  e7000_ops.to_close = e7000_close;
  e7000_ops.to_attach = 0;
  e7000_ops.to_attach = 0;
  e7000_ops.to_post_attach = NULL;
  e7000_ops.to_post_attach = NULL;
  e7000_ops.to_require_attach = NULL;
  e7000_ops.to_require_attach = NULL;
  e7000_ops.to_detach = e7000_detach;
  e7000_ops.to_detach = e7000_detach;
  e7000_ops.to_require_detach = NULL;
  e7000_ops.to_require_detach = NULL;
  e7000_ops.to_resume = e7000_resume;
  e7000_ops.to_resume = e7000_resume;
  e7000_ops.to_wait = e7000_wait;
  e7000_ops.to_wait = e7000_wait;
  e7000_ops.to_post_wait = NULL;
  e7000_ops.to_post_wait = NULL;
  e7000_ops.to_fetch_registers = e7000_fetch_register;
  e7000_ops.to_fetch_registers = e7000_fetch_register;
  e7000_ops.to_store_registers = e7000_store_register;
  e7000_ops.to_store_registers = e7000_store_register;
  e7000_ops.to_prepare_to_store = e7000_prepare_to_store;
  e7000_ops.to_prepare_to_store = e7000_prepare_to_store;
  e7000_ops.to_xfer_memory = e7000_xfer_inferior_memory;
  e7000_ops.to_xfer_memory = e7000_xfer_inferior_memory;
  e7000_ops.to_files_info = e7000_files_info;
  e7000_ops.to_files_info = e7000_files_info;
  e7000_ops.to_insert_breakpoint = e7000_insert_breakpoint;
  e7000_ops.to_insert_breakpoint = e7000_insert_breakpoint;
  e7000_ops.to_remove_breakpoint = e7000_remove_breakpoint;
  e7000_ops.to_remove_breakpoint = e7000_remove_breakpoint;
  e7000_ops.to_terminal_init = 0;
  e7000_ops.to_terminal_init = 0;
  e7000_ops.to_terminal_inferior = 0;
  e7000_ops.to_terminal_inferior = 0;
  e7000_ops.to_terminal_ours_for_output = 0;
  e7000_ops.to_terminal_ours_for_output = 0;
  e7000_ops.to_terminal_ours = 0;
  e7000_ops.to_terminal_ours = 0;
  e7000_ops.to_terminal_info = 0;
  e7000_ops.to_terminal_info = 0;
  e7000_ops.to_kill = e7000_kill;
  e7000_ops.to_kill = e7000_kill;
  e7000_ops.to_load = e7000_load;
  e7000_ops.to_load = e7000_load;
  e7000_ops.to_lookup_symbol = 0;
  e7000_ops.to_lookup_symbol = 0;
  e7000_ops.to_create_inferior = e7000_create_inferior;
  e7000_ops.to_create_inferior = e7000_create_inferior;
  e7000_ops.to_post_startup_inferior = NULL;
  e7000_ops.to_post_startup_inferior = NULL;
  e7000_ops.to_acknowledge_created_inferior = NULL;
  e7000_ops.to_acknowledge_created_inferior = NULL;
  e7000_ops.to_clone_and_follow_inferior = NULL;
  e7000_ops.to_clone_and_follow_inferior = NULL;
  e7000_ops.to_post_follow_inferior_by_clone = NULL;
  e7000_ops.to_post_follow_inferior_by_clone = NULL;
  e7000_ops.to_insert_fork_catchpoint = NULL;
  e7000_ops.to_insert_fork_catchpoint = NULL;
  e7000_ops.to_remove_fork_catchpoint = NULL;
  e7000_ops.to_remove_fork_catchpoint = NULL;
  e7000_ops.to_insert_vfork_catchpoint = NULL;
  e7000_ops.to_insert_vfork_catchpoint = NULL;
  e7000_ops.to_remove_vfork_catchpoint = NULL;
  e7000_ops.to_remove_vfork_catchpoint = NULL;
  e7000_ops.to_has_forked = NULL;
  e7000_ops.to_has_forked = NULL;
  e7000_ops.to_has_vforked = NULL;
  e7000_ops.to_has_vforked = NULL;
  e7000_ops.to_can_follow_vfork_prior_to_exec = NULL;
  e7000_ops.to_can_follow_vfork_prior_to_exec = NULL;
  e7000_ops.to_post_follow_vfork = NULL;
  e7000_ops.to_post_follow_vfork = NULL;
  e7000_ops.to_insert_exec_catchpoint = NULL;
  e7000_ops.to_insert_exec_catchpoint = NULL;
  e7000_ops.to_remove_exec_catchpoint = NULL;
  e7000_ops.to_remove_exec_catchpoint = NULL;
  e7000_ops.to_has_execd = NULL;
  e7000_ops.to_has_execd = NULL;
  e7000_ops.to_reported_exec_events_per_exec_call = NULL;
  e7000_ops.to_reported_exec_events_per_exec_call = NULL;
  e7000_ops.to_has_exited = NULL;
  e7000_ops.to_has_exited = NULL;
  e7000_ops.to_mourn_inferior = e7000_mourn_inferior;
  e7000_ops.to_mourn_inferior = e7000_mourn_inferior;
  e7000_ops.to_can_run = 0;
  e7000_ops.to_can_run = 0;
  e7000_ops.to_notice_signals = 0;
  e7000_ops.to_notice_signals = 0;
  e7000_ops.to_thread_alive = 0;
  e7000_ops.to_thread_alive = 0;
  e7000_ops.to_stop = e7000_stop;
  e7000_ops.to_stop = e7000_stop;
  e7000_ops.to_pid_to_exec_file = NULL;
  e7000_ops.to_pid_to_exec_file = NULL;
  e7000_ops.to_core_file_to_sym_file = NULL;
  e7000_ops.to_core_file_to_sym_file = NULL;
  e7000_ops.to_stratum = process_stratum;
  e7000_ops.to_stratum = process_stratum;
  e7000_ops.DONT_USE = 0;
  e7000_ops.DONT_USE = 0;
  e7000_ops.to_has_all_memory = 1;
  e7000_ops.to_has_all_memory = 1;
  e7000_ops.to_has_memory = 1;
  e7000_ops.to_has_memory = 1;
  e7000_ops.to_has_stack = 1;
  e7000_ops.to_has_stack = 1;
  e7000_ops.to_has_registers = 1;
  e7000_ops.to_has_registers = 1;
  e7000_ops.to_has_execution = 1;
  e7000_ops.to_has_execution = 1;
  e7000_ops.to_sections = 0;
  e7000_ops.to_sections = 0;
  e7000_ops.to_sections_end = 0;
  e7000_ops.to_sections_end = 0;
  e7000_ops.to_magic = OPS_MAGIC;
  e7000_ops.to_magic = OPS_MAGIC;
};
};
 
 
void
void
_initialize_remote_e7000 ()
_initialize_remote_e7000 ()
{
{
  init_e7000_ops ();
  init_e7000_ops ();
  add_target (&e7000_ops);
  add_target (&e7000_ops);
 
 
  add_com ("e7000", class_obscure, e7000_command,
  add_com ("e7000", class_obscure, e7000_command,
           "Send a command to the e7000 monitor.");
           "Send a command to the e7000 monitor.");
 
 
  add_com ("ftplogin", class_obscure, e7000_login_command,
  add_com ("ftplogin", class_obscure, e7000_login_command,
           "Login to machine and change to directory.");
           "Login to machine and change to directory.");
 
 
  add_com ("ftpload", class_obscure, e7000_ftp_command,
  add_com ("ftpload", class_obscure, e7000_ftp_command,
           "Fetch and load a file from previously described place.");
           "Fetch and load a file from previously described place.");
 
 
  add_com ("drain", class_obscure, e7000_drain_command,
  add_com ("drain", class_obscure, e7000_drain_command,
           "Drain pending e7000 text buffers.");
           "Drain pending e7000 text buffers.");
 
 
  add_show_from_set (add_set_cmd ("usehardbreakpoints", no_class,
  add_show_from_set (add_set_cmd ("usehardbreakpoints", no_class,
                                var_integer, (char *) &use_hard_breakpoints,
                                var_integer, (char *) &use_hard_breakpoints,
        "Set use of hardware breakpoints for all breakpoints.\n", &setlist),
        "Set use of hardware breakpoints for all breakpoints.\n", &setlist),
                     &showlist);
                     &showlist);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.