Fix a typo in bunzip2..
[deliverable/binutils-gdb.git] / gdb / remote-est.c
index 1fbdfac8738aa9bb25ff38c3152fa31d70af14b4..884429ac28cdaf8bdb92101cc2a29c5651b1ca58 100644 (file)
@@ -1,8 +1,10 @@
 /* Remote debugging interface for EST-300 ICE, for GDB
-   Copyright 1994 Free Software Foundation, Inc.
+   Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
    Contributed by Cygnus Support.
 
    Written by Steve Chamberlain for Cygnus Support.
+   Re-written by Stu Grossman of Cygnus Support
 
    This file is part of GDB.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
+   Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
-#include "command.h"
 #include "gdbcore.h"
 #include "target.h"
-#include "wait.h"
-#include <varargs.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/types.h>
+#include "monitor.h"
 #include "serial.h"
-#include "remote-utils.h"
-
-
-static void expect_char PARAMS ((int));
-
-
-static void 
-write_and_expect (x)
-char *x;
-{
-  sr_write_cr (x);
-  sr_expect (x);
-}
-
-static void
-expect_char (want)
-     int want;
-{
-  int c = sr_readchar ();
-  while (c != want)
-    c = sr_readchar ();
-}
-
-
-static void
-expect_prompt ()
-{
-  expect_char ('>');
-}
-
-static int
-get_hex_digit (ch)
-     int ch;
-{
-  if (ch >= '0' && ch <= '9')
-    return ch - '0';
-  else if (ch >= 'A' && ch <= 'F')
-    return ch - 'A' + 10;
-  else if (ch >= 'a' && ch <= 'f')
-    return ch - 'a' + 10;
-  return -1;
-}
-
-static int
-get_hex (start)
-     int *start;
-{
-  int value = get_hex_digit (*start);
-  int try;
-
-  *start = sr_readchar ();
-  while ((try = get_hex_digit (*start)) >= 0)
-    {
-      value <<= 4;
-      value += try;
-      *start = sr_readchar ();
-    }
-  return value;
-}
-
-/* Tell the remote machine to resume.  */
-
-static void
-est_resume (pid, step, sig)
-     int pid, step, sig;
-{
-  write_and_expect (step ? ".SI" : ".GO");
-}
-
-/* A reg dump looks like
-  D0 = 00000000 D1 = 00000000 D2 = 00000000 D3 = 00000000
-  D4 = 00000000 D5 = 00000000 D6 = 00000000 D7 = 00000000
-  A0 = 00000000 A1 = 00000000 A2 = 00000000 A3 = 00000000
-  A4 = 00000000 A5 = 00000000 A6 = 00000000 A7 = 001104FE
-  USP = 00110400 SSP*= 001104FE PC = 00229BBC SR = 2000
-  VBR = 00110000 SFC = 0005 DFC = 0005
-
-or
-
-00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00001234 00000000 001104FE 00110400 001104FE 00229BBC 2000 00110000 0005 0005
-*/
-
-static int 
-target_to_gdb_rn (rn)
-     int rn;
-{
-  if (rn < 16)
-    return rn;
-  if (rn == 18)
-    return PC_REGNUM;
-  if (rn == 19)
-    return PS_REGNUM;
-  return -1;
-}
+#include "regcache.h"
 
+#include "m68k-tdep.h"
 
-static void est_fetch_register ();
-static void
-est_fetch_registers ()
-{
-  int regno;
-  unsigned long val;
-  int c;
-  int target_rn;
-  char buf[4];
-  write_and_expect (".DR");
-  buf[0] = 0;
-  buf[1] = 0;
-  buf[2] = 0;
-  buf[3] = 0;
-  for (regno = 0; regno < NUM_REGS; regno++)
-    supply_register (regno, buf);
-
-  c = sr_readchar ();
-  for (target_rn = 0; target_rn < 23; target_rn++)
-    {
-      unsigned long val;
-      while (!isdigit (c) && !isalpha (c))
-       c = sr_readchar ();
-
-      while (isdigit (c) || (c >= 'A' && c <= 'F'))
-       {
-         val <<= 4;
-         if (isdigit (c))
-           val = val + c - '0';
-         else
-           val = val + c - 'A' + 10;
-         c = sr_readchar ();
-       }
-
-      regno = target_to_gdb_rn (target_rn);
-      if (regno >= 0)
-       {
-         buf[0] = val >> 24;
-         buf[1] = val >> 16;
-         buf[2] = val >> 8;
-         buf[3] = val >> 0;
-         supply_register (regno, buf);
-       }
-    }
-  expect_prompt();
-}
+static void est_open (char *args, int from_tty);
 
-/* Fetch register REGNO, or all registers if REGNO is -1.
-   Returns errno value.  */
-
-static
-void
-est_fetch_register (regno)
-     int regno;
-{
-  est_fetch_registers ();
-}
-
-/* Store the remote registers from the contents of the block REGS.  */
-
-static void est_store_register ();
 static void
-est_store_registers ()
+est_supply_register (char *regname, int regnamelen, char *val, int vallen)
 {
   int regno;
 
-  for (regno = 0; regno < 18; regno++)
-    est_store_register (regno);
-  registers_changed ();
-}
-
-/* Store register REGNO, or all if REGNO == 0.
-   Return errno value.  */
-static void
-est_store_register (regno)
-     int regno;
-{
-  char buf[20];
-  if (regno == -1)
-    {
-      est_store_registers ();
-      return;
-    }
-
-  if (regno < 8)
-    sprintf (buf, ".SR D%d %x", regno, read_register (regno));
-  else if (regno < 16)
-    sprintf (buf, ".SR A%d %x", regno - 8, read_register (regno));
-  else if (regno == PC_REGNUM)
-    sprintf (buf, ".SR PC %x", read_register (regno));
-  else if (regno == PS_REGNUM)
-    sprintf (buf, ".SR SR %x", read_register (regno));
-  else
+  if (regnamelen != 2)
     return;
-  write_and_expect (buf);
-  expect_prompt ();
-}
-
-/* Get ready to modify the registers array.  On machines which store
-   individual registers, this doesn't need to do anything.  On machines
-   which store all the registers in one fell swoop, this makes sure
-   that registers contains all the registers from the program being
-   debugged.  */
-
 
-static
-int
-stickbyte (where, what)
-     char *where;
-     unsigned int what;
-{
-  static CONST char digs[] = "0123456789ABCDEF";
-  where[0] = digs[(what >> 4) & 0xf];
-  where[1] = digs[(what & 0xf) & 0xf];
-  return what;
-}
-
-/* Copy LEN bytes of data from debugger memory at MYADDR
-   to inferior's memory at MEMADDR.  Returns length moved.   */
-
-static int
-est_write_memory (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     unsigned char *myaddr;
-     int len;
-{
-  int i;
-#define maxstride  128
-  int stride;
-
-  write_and_expect (".DL");
-  expect_char ('+');
-  for (i = 0; i < len; i += stride)
+  switch (regname[0])
     {
-      char compose[maxstride * 2 + 50];
-      int address = i + memaddr;
-      int j;
-      int check_sum;
-      int where = 0;
-      int alen;
-      stride = len - i;
-      if (stride > maxstride)
-       stride = maxstride;
-
-      compose[where++] = 'S';
-      check_sum = 0;
-      if (address >= 0xffffff)
-       {
-         alen = 4;
-       }
-      else if (address >= 0xffff)
-       {
-         alen = 3;
-       }
-      else
-       alen = 2;
-      compose[where++] = alen - 1 + '0';       /* insert type */
-      check_sum += stickbyte (compose + where, alen + stride + 1);     /* Insert length */
-      where += 2;
-      while (alen > 0)
-       {
-         alen--;
-         check_sum += stickbyte (compose + where, address >> (8 * (alen)));
-         where += 2;
-       }
-
-      for (j = 0; j < stride; j++)
-       {
-         check_sum += stickbyte (compose + where, myaddr[i + j]);
-         where += 2;
-       }
-
-      stickbyte (compose + where, ~check_sum);
-
-      where += 2;
-      compose[where++] = 0;
-
-      sr_write_cr (compose);
-      while (sr_readchar () != '+')
-         sr_write_cr (compose);
+    case 'S':
+      if (regname[1] != 'R')
+       return;
+      regno = PS_REGNUM;
+      break;
+    case 'P':
+      if (regname[1] != 'C')
+       return;
+      regno = PC_REGNUM;
+      break;
+    case 'D':
+      if (regname[1] < '0' || regname[1] > '7')
+       return;
+      regno = regname[1] - '0' + M68K_D0_REGNUM;
+      break;
+    case 'A':
+      if (regname[1] < '0' || regname[1] > '7')
+       return;
+      regno = regname[1] - '0' + M68K_A0_REGNUM;
+      break;
+    default:
+      return;
     }
 
-  /* Send the trailer record */
-  sr_write_cr ("S70500000000FA");
-  expect_prompt ();
-  return len;
+  monitor_supply_register (regno, val);
 }
 
-
-
 /*
-
-   The dump memory command generates output which looks like:
-
-
-.dmb 0 100
-4E 56 FF FC 4E 71 42 AE FF FC 72 09 B2 AE FF FC     NV..NqB...r.....
-6C 02 60 12 2F 2E FF FC 4E B9 00 00 00 2A 58 4F     l.`./...N....*XO
-52 AE FF FC 60 E4 4E 5E 4E 75 4E 56 00 00 20 2E     R...`.N^NuNV.. .
-00 08 D1 B9 00 00 00 00 4E 5E 4E 75 06 46 40 54     ........N^Nu.F@T
-04 45 44 4C 54 45 40 56 42 F4 04 64 24 45 05 05     .EDLTE@VB..d$E..
-00 6D 04 46 00 45 4C 05 04 46 04 4C 44 CD 00 65     .m.F.EL..F.LD..e
-40 45 44 55 45 45 45 46 04 44 44 40 05 4D 00 44     @EDUEEEF.DD@.M.D
-
-*/
-
-static int
-est_read_memory (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     unsigned char *myaddr;
-     int len;
-{
-  int count;
-  int c;
-  char buf[20];
-  /* Starting address of this pass.  */
-
-  if (((memaddr - 1) + len) < memaddr)
-    {
-      errno = EIO;
-      return 0;
-    }
-
-  sprintf (buf, ".dmb %x %x", memaddr, len);
-  write_and_expect (buf);
-  count = 0;
-
-  c = sr_readchar ();
-
-  while (count < len)
-    {
-      while (!isdigit (c) && !isalpha (c)) {
-       if (c == '!')
-         {
-           expect_prompt();
-           errno =EIO;
-           return 0;
-
-         }
-       c = sr_readchar ();
-      }
-      myaddr[count++] = get_hex (&c);
-      c = sr_readchar ();
-      if (c == ' ')
-       {
-         c = sr_readchar ();
-         if (c == ' ')
-           while (c != '\r')
-             c = sr_readchar ();
-       }
-    }
-
-  expect_prompt ();
-
-
-  return len;
-}
-
-static int
-est_xfer_inferior_memory (memaddr, myaddr, len, write, target)
-     CORE_ADDR memaddr;
-     unsigned char *myaddr;
-     int len;
-     int write;
-     struct target_ops *target;        /* ignored */
-{
-  if (write)
-    {
-      return est_write_memory (memaddr, myaddr, len);
-    }
+ * This array of registers needs to match the indexes used by GDB. The
+ * whole reason this exists is because the various ROM monitors use
+ * different names than GDB does, and don't support all the
+ * registers either. So, typing "info reg sp" becomes a "r30".
+ */
+
+static const char *
+est_regname (int index) 
+{
+  
+  static char *regnames[] =
+  {
+    "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
+    "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
+    "SR", "PC",
+  };
+  
+
+  if ((index >= (sizeof (regnames) /  sizeof (regnames[0]))) 
+       || (index < 0) || (index >= NUM_REGS))
+    return NULL;
   else
-    {
-      return est_read_memory (memaddr, myaddr, len);
-    }
+    return regnames[index];
 }
 
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
 
-#define MAX_DEBUG_BREAKPOINTS 100
-
-extern int memory_breakpoint_size;
-static CORE_ADDR breakaddr[MAX_DEBUG_BREAKPOINTS] =
-{0};
-
-int 
-est_clear_all_breakpoints ()
-{
-  int i;
-  for (i = 0; i < MAX_DEBUG_BREAKPOINTS; i++)
-    {
-      breakaddr[i] = 0;
-    }
-
-  if (sr_is_open ())
-    {
-      write_and_expect (".RB");
-      expect_prompt ();
-    }
-  return 0;
-}
-
-static int
-est_insert_breakpoint (addr, shadow)
-     CORE_ADDR addr;
-     unsigned char *shadow;
-{
-  int i;
-
-  for (i = 0; i <= MAX_DEBUG_BREAKPOINTS; i++)
-    if (breakaddr[i] == 0)
-      {
-       char buf[20];
-       breakaddr[i] = addr;
-       sprintf (buf, ".SB %x", addr);
-       write_and_expect (buf);
-       expect_prompt ();
-       return 0;
-      }
-  error ("Too many breakpoints ( > %d) for the est\n", MAX_DEBUG_BREAKPOINTS);
-  return 1;
-}
-
-static int
-est_remove_breakpoint (addr, shadow)
-     CORE_ADDR addr;
-     unsigned char *shadow;
-{
-  int i;
-
-  for (i = 0; i < MAX_DEBUG_BREAKPOINTS; i++)
-    if (breakaddr[i] == addr)
-      {
-       char buf[20];
-       breakaddr[i] = 0;
-       sprintf (buf, ".RB %x", addr);
-       write_and_expect (buf);
-       expect_prompt ();
-       return 0;
-      }
-
-  error ("Can't find breakpoint associated with 0x%x\n", addr);
-  return 1;
-}
-
+static struct target_ops est_ops;
 
-/* Wait until the remote machine stops, then return,
-   storing status in STATUS just as `wait' would.  */
+static char *est_inits[] =
+{"he\r",                       /* Resets the prompt, and clears repeated cmds */
+ NULL};
 
-static int
-est_wait (pid, status)
-     int pid;
-     struct target_waitstatus *status;
-{
-  int c = sr_readchar ();
-  while (c != '!')
-    c = sr_readchar ();
-  /* What sort of stop */
-  c = sr_readchar ();
-  status->kind = TARGET_WAITKIND_STOPPED;
-  switch (c)
-    {
-    case 'E':
-      status->value.sig = TARGET_SIGNAL_BUS;
-      break;
-      /* Address error */
-    case 'A':
-      status->value.sig = TARGET_SIGNAL_BUS;
-      break;
-      /* Break */
-    case 'B':
-      status->value.sig = TARGET_SIGNAL_TRAP;
-      break;
-    }
-  expect_prompt ();
-  return 0;
-}
+static struct monitor_ops est_cmds;
 
-void 
-est_checkin ()
-{
-  write_and_expect (".in");
-  gr_expect_prompt ();
-}
-
-extern struct gr_settings est_settings;
+static void
+init_est_cmds (void)
+{
+  est_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_FILL_USES_ADDR | MO_NEED_REGDUMP_AFTER_CONT |
+    MO_SREC_ACK | MO_SREC_ACK_PLUS;
+  est_cmds.init = est_inits;   /* Init strings */
+  est_cmds.cont = "go\r";      /* continue command */
+  est_cmds.step = "sidr\r";    /* single step */
+  est_cmds.stop = "\003";      /* ^C interrupts the program */
+  est_cmds.set_break = "sb %x\r";      /* set a breakpoint */
+  est_cmds.clr_break = "rb %x\r";      /* clear a breakpoint */
+  est_cmds.clr_all_break = "rb\r";     /* clear all breakpoints */
+  est_cmds.fill = "bfb %x %x %x\r";    /* fill (start end val) */
+  est_cmds.setmem.cmdb = "smb %x %x\r";                /* setmem.cmdb (addr, value) */
+  est_cmds.setmem.cmdw = "smw %x %x\r";                /* setmem.cmdw (addr, value) */
+  est_cmds.setmem.cmdl = "sml %x %x\r";                /* setmem.cmdl (addr, value) */
+  est_cmds.setmem.cmdll = NULL;        /* setmem.cmdll (addr, value) */
+  est_cmds.setmem.resp_delim = NULL;   /* setreg.resp_delim */
+  est_cmds.setmem.term = NULL; /* setreg.term */
+  est_cmds.setmem.term_cmd = NULL;     /* setreg.term_cmd */
+  est_cmds.getmem.cmdb = "dmb %x %x\r";                /* getmem.cmdb (addr, len) */
+  est_cmds.getmem.cmdw = "dmw %x %x\r";                /* getmem.cmdw (addr, len) */
+  est_cmds.getmem.cmdl = "dml %x %x\r";                /* getmem.cmdl (addr, len) */
+  est_cmds.getmem.cmdll = NULL;        /* getmem.cmdll (addr, len) */
+  est_cmds.getmem.resp_delim = ": ";   /* getmem.resp_delim */
+  est_cmds.getmem.term = NULL; /* getmem.term */
+  est_cmds.getmem.term_cmd = NULL;     /* getmem.term_cmd */
+  est_cmds.setreg.cmd = "sr %s %x\r";  /* setreg.cmd (name, value) */
+  est_cmds.setreg.resp_delim = NULL;   /* setreg.resp_delim */
+  est_cmds.setreg.term = NULL; /* setreg.term */
+  est_cmds.setreg.term_cmd = NULL;     /* setreg.term_cmd */
+  est_cmds.getreg.cmd = "dr %s\r";     /* getreg.cmd (name) */
+  est_cmds.getreg.resp_delim = " = ";  /* getreg.resp_delim */
+  est_cmds.getreg.term = NULL; /* getreg.term */
+  est_cmds.getreg.term_cmd = NULL;     /* getreg.term_cmd */
+  est_cmds.dump_registers = "dr\r";    /* dump_registers */
+  est_cmds.register_pattern = "\\(\\w+\\) = \\([0-9a-fA-F]+\\)";       /* register_pattern */
+  est_cmds.supply_register = est_supply_register;
+  est_cmds.load_routine = NULL;        /* load_routine (defaults to SRECs) */
+  est_cmds.load = "dl\r";      /* download command */
+  est_cmds.loadresp = "+";     /* load response */
+  est_cmds.prompt = ">BKM>";   /* monitor command prompt */
+  est_cmds.line_term = "\r";   /* end-of-line terminator */
+  est_cmds.cmd_end = NULL;     /* optional command terminator */
+  est_cmds.target = &est_ops;  /* target operations */
+  est_cmds.stopbits = SERIAL_1_STOPBITS;       /* number of stop bits */
+  est_cmds.regnames = NULL;
+  est_cmds.regname = est_regname; /*register names*/
+  est_cmds.magic = MONITOR_OPS_MAGIC;  /* magic */
+}                              /* init_est_cmds */
 
 static void
-est_open (args, from_tty)
-     char *args;
-     int from_tty;
+est_open (char *args, int from_tty)
 {
-  gr_open (args, from_tty, &est_settings);
+  monitor_open (args, &est_cmds, from_tty);
 }
 
-/* Define the target subroutine names */
+extern initialize_file_ftype _initialize_est; /* -Wmissing-prototypes */
 
-struct target_ops est_ops =
+void
+_initialize_est (void)
 {
-  "est",
-  "Remote EST-300 target",
-  "Use a remote EST-300 ICE connected by a serial line,\n\
-or a network connection.\n\
-Arguments are the name of the device for the serial line,\n\
-the speed to connect at in bits per second.\n\
-eg\n\
-target est /dev/ttya 9600\n\
-target est foobar",
-  est_open,
-  gr_close,
-  0,
-  gr_detach,
-  est_resume,
-  est_wait,
-  est_fetch_register,
-  est_store_register,
-  gr_prepare_to_store,
-  est_xfer_inferior_memory,
-  gr_files_info,
-  est_insert_breakpoint,
-  est_remove_breakpoint,       /* Breakpoints */
-  0,
-  0,
-  0,
-  0,
-  0,                           /* Terminal handling */
-  gr_kill,
-  gr_load_image,               /* load */
-  0,                           /* lookup_symbol */
-  gr_create_inferior,
-  gr_mourn,
-  0,                           /* can_run */
-  0,                           /* notice_signals */
-  0,                           /* to_stop */
-  process_stratum,
-  0,                           /* next */
-  1,
-  1,
-  1,
-  1,
-  1,                           /* all mem, mem, stack, regs, exec */
-  0,
-  0,                           /* Section pointers */
-  OPS_MAGIC,                   /* Always the last thing */
-};
+  init_est_cmds ();
+  init_monitor_ops (&est_ops);
 
-static struct gr_settings est_settings =
-{
-  NULL,                                /* dcache */
-  ">",                         /* prompt */
-  &est_ops,                    /* ops */
-  est_clear_all_breakpoints,
-  est_read_memory,             /* readfunc */
-  est_write_memory,            /* writefunc */
-  est_checkin,                 /* checkin */
-};
+  est_ops.to_shortname = "est";
+  est_ops.to_longname = "EST background debug monitor";
+  est_ops.to_doc = "Debug via the EST BDM.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).";
+  est_ops.to_open = est_open;
 
-void
-_initialize_remote_est ()
-{
   add_target (&est_ops);
 }
This page took 0.03096 seconds and 4 git commands to generate.