* remote-est.c: New file supports EST-300 CPU32 background
authorSteve Chamberlain <sac@cygnus>
Sat, 24 Dec 1994 01:12:47 +0000 (01:12 +0000)
committerSteve Chamberlain <sac@cygnus>
Sat, 24 Dec 1994 01:12:47 +0000 (01:12 +0000)
mode ICE.
* remote-utils.c (sr_com):  Call registers_changed.
* configure.in (m68*-*-est*):  New configuration.
* config/m68k/tm-est.h:  New file.

gdb/.Sanitize
gdb/ChangeLog
gdb/configure.in
gdb/remote-est.c [new file with mode: 0644]
gdb/remote-utils.c

index 7cd9a148fc970a4535b8e9c556028fe04786ff77..d7079641258c3834547f9d523220bd8eb89a551d 100644 (file)
@@ -228,6 +228,7 @@ remote-bug.c
 remote-e7000.c
 remote-eb.c
 remote-es.c
+remote-est.c
 remote-hms.c
 remote-mips.c
 remote-mm.c
index 36b3318c80917e69024e6705d004e3dde767b0ee..d8b0969564826d29cf03a4b04fac5031fced89c9 100644 (file)
@@ -1,3 +1,11 @@
+Fri Dec 23 17:03:13 1994  Steve Chamberlain  (sac@jonny.cygnus.com)
+
+       * remote-est.c:  New file supports EST-300 CPU32 background 
+       mode ICE.
+       * remote-utils.c (sr_com):  Call registers_changed.
+       * configure.in (m68*-*-est*):  New configuration.
+       * config/m68k/tm-est.h:  New file.
+
 Fri Dec 23 16:18:50 1994  Stu Grossman  (grossman@cygnus.com)
 
        * Makefile.in (CLIBS):  Put LIBIBERTY last.
index e89f27f1c34c9d0981a16c0cba302a11d3cb45e2..7f14b2f40025500343c649615a2f83742883b140 100644 (file)
@@ -273,6 +273,7 @@ m68*-*-sunos3*)             gdb_target=sun3os3 ;;
 m68*-*-sunos4*)                gdb_target=sun3os4 ;;
 m68*-*-sysv4*)         gdb_target=m68kv4 ;;
 m68*-*-vxworks*)       gdb_target=vxworks68 ;;
+m68*-*-est*)           gdb_target=est ;;
 
 m88*-harris-cxux*)     gdb_target=cxux ;;
 m88*-motorola-sysv4*)  gdb_target=delta88v4 ;;
diff --git a/gdb/remote-est.c b/gdb/remote-est.c
new file mode 100644 (file)
index 0000000..1fbdfac
--- /dev/null
@@ -0,0 +1,589 @@
+/* Remote debugging interface for EST-300 ICE, for GDB
+   Copyright 1994 Free Software Foundation, Inc.
+   Contributed by Cygnus Support.
+
+   Written by Steve Chamberlain for Cygnus Support.
+
+   This file is part of GDB.
+
+   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
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   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.  */
+
+
+#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 "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;
+}
+
+
+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();
+}
+
+/* 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 ()
+{
+  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
+    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)
+    {
+      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);
+    }
+
+  /* Send the trailer record */
+  sr_write_cr ("S70500000000FA");
+  expect_prompt ();
+  return len;
+}
+
+
+
+/*
+
+   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);
+    }
+  else
+    {
+      return est_read_memory (memaddr, myaddr, len);
+    }
+}
+
+
+#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;
+}
+
+
+/* Wait until the remote machine stops, then return,
+   storing status in STATUS just as `wait' would.  */
+
+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;
+}
+
+void 
+est_checkin ()
+{
+  write_and_expect (".in");
+  gr_expect_prompt ();
+}
+
+extern struct gr_settings est_settings;
+
+static void
+est_open (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  gr_open (args, from_tty, &est_settings);
+}
+
+/* Define the target subroutine names */
+
+struct target_ops est_ops =
+{
+  "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 */
+};
+
+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 */
+};
+
+void
+_initialize_remote_est ()
+{
+  add_target (&est_ops);
+}
index f1e949a8b293ae81dcf3d09e16ab4c557506f7a7..b23aa7057f7eaa5fe9228b5886bcfba21531f637 100644 (file)
@@ -396,6 +396,7 @@ sr_com (args, fromtty)
 
   sr_write_cr (args);
   sr_write ("\030", 1);
+  registers_changed ();
   gr_expect_prompt ();
 }