aboutsummaryrefslogtreecommitdiff
path: root/gdb/remote-st2000.c
diff options
context:
space:
mode:
authorStu Grossman <grossman@cygnus>1992-06-09 23:31:53 +0000
committerStu Grossman <grossman@cygnus>1992-06-09 23:31:53 +0000
commit55488e9ea6834a9efe6432f5fc8ddf9b88023333 (patch)
tree26d649796a5322adcdb3c2130d744c6e2de0ff0f /gdb/remote-st2000.c
parent65bfcf2e612af31e16b067ffb4113b6b293f041e (diff)
downloadgdb-55488e9ea6834a9efe6432f5fc8ddf9b88023333.zip
gdb-55488e9ea6834a9efe6432f5fc8ddf9b88023333.tar.gz
gdb-55488e9ea6834a9efe6432f5fc8ddf9b88023333.tar.bz2
* depend: rebuild to account for remote-st2000.c.
* remote-st2000.c: Almost works now. * tm-st2000.h: Need to turn on HAVE_68881, else things won't compile.
Diffstat (limited to 'gdb/remote-st2000.c')
-rw-r--r--gdb/remote-st2000.c664
1 files changed, 250 insertions, 414 deletions
diff --git a/gdb/remote-st2000.c b/gdb/remote-st2000.c
index 778df86..f8a4ef3 100644
--- a/gdb/remote-st2000.c
+++ b/gdb/remote-st2000.c
@@ -1,4 +1,4 @@
-/* Remote debugging interface for AMD 29000 EBMON on IBM PC, for GDB.
+/* Remote debugging interface for Tandem ST2000 phone switch, for GDB.
Copyright 1990, 1991, 1992 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Jim Kingdon for Cygnus.
@@ -18,34 +18,38 @@ 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. */
-/* This is like remote.c but is for an esoteric situation--
+/* This file was derived from remote-eb.c, which did a similar job, but for
+ an AMD-29K running EBMON. That file was in turn derived from remote.c
+ as mentioned in the following comment (left in for comic relief):
+
+ "This is like remote.c but is for an esoteric situation--
having a 29k board in a PC hooked up to a unix machine with
a serial line, and running ctty com1 on the PC, through which
the unix machine can run ebmon. Not to mention that the PC
has PC/NFS, so it can access the same executables that gdb can,
- over the net in real time. */
+ over the net in real time."
-#define TM_FILE_OVERRIDE
-#include "defs.h"
-#include <string.h>
-#include "tm-29k.h"
+ In reality, this module talks to a debug monitor called 'STDEBUG', which
+ runs in a phone switch. We communicate with STDEBUG via either a direct
+ serial line, or a TCP (or possibly TELNET) stream to a terminal multiplexor,
+ which in turn talks to the phone switch. */
-#include "inferior.h"
-#include "wait.h"
-#include "value.h"
-#include <ctype.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <errno.h>
+#include "defs.h"
+#include "gdbcore.h"
#include "terminal.h"
#include "target.h"
-#include "gdbcore.h"
+#include "wait.h"
+#include <varargs.h>
+#include <signal.h>
+#include <string.h>
-extern struct target_ops eb_ops; /* Forward declaration */
+extern struct target_ops st2000_ops; /* Forward declaration */
-static void eb_close();
+static void st2000_close();
+static void st2000_fetch_register();
+static void st2000_store_register();
-#define LOG_FILE "eb.log"
+#define LOG_FILE "st2000.log"
#if defined (LOG_FILE)
FILE *log_file;
#endif
@@ -53,13 +57,30 @@ FILE *log_file;
static int timeout = 24;
/* Descriptor for I/O to remote machine. Initialize it to -1 so that
- eb_open knows that we don't have a file open when the program
+ st2000_open knows that we don't have a file open when the program
starts. */
-int eb_desc = -1;
+int st2000_desc = -1;
+
+/* stream which is fdopen'd from st2000_desc. Only valid when
+ st2000_desc != -1. */
+FILE *st2000_stream;
-/* stream which is fdopen'd from eb_desc. Only valid when
- eb_desc != -1. */
-FILE *eb_stream;
+/* Send data to stdebug. Works just like printf. */
+
+static void
+printf_stdebug(va_alist)
+ va_dcl
+{
+ va_list args;
+ char *pattern;
+
+ va_start(args);
+
+ pattern = va_arg(args, char *);
+
+ vfprintf(st2000_stream, pattern, args);
+ fflush(st2000_stream);
+}
/* Read a character from the remote system, doing all the fancy
timeout stuff. */
@@ -71,10 +92,10 @@ readchar ()
buf = '\0';
#ifdef HAVE_TERMIO
/* termio does the timeout for us. */
- read (eb_desc, &buf, 1);
+ read (st2000_desc, &buf, 1);
#else
alarm (timeout);
- if (read (eb_desc, &buf, 1) < 0)
+ if (read (st2000_desc, &buf, 1) < 0)
{
if (errno == EINTR)
error ("Timeout reading from remote system.");
@@ -117,17 +138,17 @@ expect (string)
}
}
-/* Keep discarding input until we see the ebmon prompt.
+/* Keep discarding input until we see the STDEBUG prompt.
The convention for dealing with the prompt is that you
o give your command
o *then* wait for the prompt.
Thus the last thing that a procedure does with the serial line
- will be an expect_prompt(). Exception: eb_resume does not
+ will be an expect_prompt(). Exception: st2000_resume does not
wait for the prompt, because the terminal is being handed over
to the inferior. However, the next thing which happens after that
- is a eb_wait which does wait for the prompt.
+ is a st2000_wait which does wait for the prompt.
Note that this includes abnormal exit, e.g. error(). This is
necessary to prevent getting into states from which we can't
recover. */
@@ -139,7 +160,7 @@ expect_prompt ()
enough that we never lose much data if we terminate abnormally. */
fflush (log_file);
#endif
- expect ("\n# ");
+ expect ("dbug> ");
}
/* Get a hex digit from the remote system & return its value.
@@ -168,7 +189,7 @@ get_hex_digit (ignore_space)
}
}
-/* Get a byte from eb_desc and put it in *BYT. Accept any number
+/* Get a byte from st2000_desc and put it in *BYT. Accept any number
leading spaces. */
static void
get_hex_byte (byt)
@@ -198,7 +219,7 @@ get_hex_regs (n, regno)
val = 0;
for (j = 0; j < 8; j++)
val = (val << 4) + get_hex_digit (j == 0);
- supply_register (regno++, &val);
+ supply_register (regno++, (char *) &val);
}
}
@@ -210,34 +231,17 @@ get_hex_regs (n, regno)
#endif
volatile int n_alarms;
-void
-eb_timer ()
+static void
+st2000_timer ()
{
-#if 0
- if (kiodebug)
- printf ("eb_timer called\n");
-#endif
n_alarms++;
}
#endif
-/* malloc'd name of the program on the remote system. */
-static char *prog_name = NULL;
-
-/* Nonzero if we have loaded the file ("yc") and not yet issued a "gi"
- command. "gi" is supposed to happen exactly once for each "yc". */
-static int need_gi = 0;
-
-/* Number of SIGTRAPs we need to simulate. That is, the next
- NEED_ARTIFICIAL_TRAP calls to eb_wait should just return
- SIGTRAP without actually waiting for anything. */
-
-static int need_artificial_trap = 0;
-
/* This is called not only when we first attach, but also when the
user types "run" after having attached. */
static void
-eb_create_inferior (execfile, args, env)
+st2000_create_inferior (execfile, args, env)
char *execfile;
char *args;
char **env;
@@ -245,7 +249,7 @@ eb_create_inferior (execfile, args, env)
int entry_pt;
if (args && *args)
- error ("Can't pass arguments to remote EBMON process");
+ error ("Can't pass arguments to remote STDEBUG process");
if (execfile == 0 || exec_bfd == 0)
error ("No exec file specified");
@@ -256,23 +260,6 @@ eb_create_inferior (execfile, args, env)
CREATE_INFERIOR_HOOK (0); /* No process-ID */
#endif
- {
- /* OK, now read in the file. Y=read, C=COFF, D=no symbols
- 0=start address, %s=filename. */
-
- fprintf (eb_stream, "YC D,0:%s", prog_name);
-
- if (args != NULL)
- fprintf(eb_stream, " %s", args);
-
- fprintf (eb_stream, "\n");
- fflush (eb_stream);
-
- expect_prompt ();
-
- need_gi = 1;
- }
-
/* The "process" (board) is already stopped awaiting our commands, and
the program is already downloaded. We just set its PC and go. */
@@ -302,7 +289,7 @@ eb_create_inferior (execfile, args, env)
#define B38400 EXTB
#endif
-struct {int rate, damn_b;} baudtab[] = {
+static struct {int rate, damn_b;} baudtab[] = {
{0, B0},
{50, B50},
{75, B75},
@@ -322,7 +309,8 @@ struct {int rate, damn_b;} baudtab[] = {
{-1, -1},
};
-int damn_b (rate)
+static int
+damn_b (rate)
int rate;
{
int i;
@@ -334,13 +322,15 @@ int damn_b (rate)
/* Open a connection to a remote debugger.
- NAME is the filename used for communication, then a space,
- then the name of the program as we should name it to EBMON. */
+ NAME is the filename used for communication. */
static int baudrate = 9600;
static char *dev_name;
-void
-eb_open (name, from_tty)
+
+static TERMINAL old_sg;
+
+static void
+st2000_open (name, from_tty)
char *name;
int from_tty;
{
@@ -350,19 +340,19 @@ eb_open (name, from_tty)
target_preopen (from_tty);
- /* Find the first whitespace character, it separates dev_name from
- prog_name. */
- if (name == 0)
+ if (!name)
goto erroid;
- for (p = name;
- *p != '\0' && !isspace (*p); p++)
+ /* Find the first whitespace character, it separates dev_name from
+ the baud rate. */
+
+ for (p = name; *p && !isspace (*p); p++)
;
if (*p == '\0')
erroid:
error ("\
-Please include the name of the device for the serial port,\n\
-the baud rate, and the name of the program to run on the remote system.");
+Please include the name of the device for the serial port, and the baud rate.");
+
dev_name = alloca (p - name + 1);
strncpy (dev_name, name, p - name);
dev_name[p - name] = '\0';
@@ -374,22 +364,14 @@ the baud rate, and the name of the program to run on the remote system.");
if (1 != sscanf (p, "%d ", &baudrate))
goto erroid;
- /* Skip the number and then the spaces */
- for (; isdigit (*p); p++)
- /*EMPTY*/;
- for (; isspace (*p); p++)
- /*EMPTY*/;
-
- if (prog_name != NULL)
- free (prog_name);
- prog_name = savestring (p, strlen (p));
-
- eb_close (0);
+ st2000_close (0);
- eb_desc = open (dev_name, O_RDWR);
- if (eb_desc < 0)
+ st2000_desc = open (dev_name, O_RDWR);
+ if (st2000_desc < 0)
perror_with_name (dev_name);
- ioctl (eb_desc, TIOCGETP, &sg);
+ ioctl (st2000_desc, TIOCGETP, &sg);
+ old_sg = sg;
+
#ifdef HAVE_TERMIO
sg.c_cc[VMIN] = 0; /* read with timeout. */
sg.c_cc[VTIME] = timeout * 10;
@@ -402,25 +384,22 @@ the baud rate, and the name of the program to run on the remote system.");
sg.sg_flags &= ~ECHO;
#endif
- ioctl (eb_desc, TIOCSETP, &sg);
- eb_stream = fdopen (eb_desc, "r+");
+ ioctl (st2000_desc, TIOCSETP, &sg);
+ st2000_stream = fdopen (st2000_desc, "r+");
- push_target (&eb_ops);
- if (from_tty)
- printf ("Remote %s debugging %s using %s\n", target_shortname,
- prog_name, dev_name);
+ push_target (&st2000_ops);
#ifndef HAVE_TERMIO
#ifndef NO_SIGINTERRUPT
/* Cause SIGALRM's to make reads fail with EINTR instead of resuming
the read. */
if (siginterrupt (SIGALRM, 1) != 0)
- perror ("eb_open: error in siginterrupt");
+ perror ("st2000_open: error in siginterrupt");
#endif
/* Set up read timeout timer. */
- if ((void (*)) signal (SIGALRM, eb_timer) == (void (*)) -1)
- perror ("eb_open: error in signal");
+ if ((void (*)) signal (SIGALRM, st2000_timer) == (void (*)) -1)
+ perror ("st2000_open: error in signal");
#endif
#if defined (LOG_FILE)
@@ -430,29 +409,35 @@ the baud rate, and the name of the program to run on the remote system.");
#endif
/* Hello? Are you there? */
- write (eb_desc, "\n", 1);
+ printf_stdebug ("\r");
expect_prompt ();
+
+ if (from_tty)
+ printf ("Remote %s connected to %s\n", target_shortname,
+ dev_name);
}
/* Close out all files and local state before this target loses control. */
static void
-eb_close (quitting)
+st2000_close (quitting)
int quitting;
{
+ /* Reset the terminal to its original settings. */
+
+ ioctl (st2000_desc, TIOCSETP, &old_sg);
+
/* Due to a bug in Unix, fclose closes not only the stdio stream,
but also the file descriptor. So we don't actually close
- eb_desc. */
- if (eb_stream)
- fclose (eb_stream); /* This also closes eb_desc */
- if (eb_desc >= 0)
- /* close (eb_desc); */
+ st2000_desc. */
+ if (st2000_stream)
+ fclose (st2000_stream); /* This also closes st2000_desc */
- /* Do not try to close eb_desc again, later in the program. */
- eb_stream = NULL;
- eb_desc = -1;
+ /* Do not try to close st2000_desc again, later in the program. */
+ st2000_stream = NULL;
+ st2000_desc = -1;
#if defined (LOG_FILE)
if (log_file) {
@@ -467,74 +452,46 @@ eb_close (quitting)
/* Terminate the open connection to the remote debugger.
Use this when you want to detach and do something else
with your gdb. */
-void
-eb_detach (from_tty)
+static void
+st2000_detach (from_tty)
int from_tty;
{
- pop_target(); /* calls eb_close to do the real work */
+ pop_target(); /* calls st2000_close to do the real work */
if (from_tty)
printf ("Ending remote %s debugging\n", target_shortname);
}
/* Tell the remote machine to resume. */
-void
-eb_resume (step, sig)
+static void
+st2000_resume (step, sig)
int step, sig;
{
if (step)
{
- write (eb_desc, "t 1,s\n", 6);
+ printf_stdebug ("ST\r");
/* Wait for the echo. */
- expect ("t 1,s\r");
- /* Then comes a line containing the instruction we stepped to. */
- expect ("\n@");
- /* Then we get the prompt. */
- expect_prompt ();
-
- /* Force the next eb_wait to return a trap. Not doing anything
- about I/O from the target means that the user has to type
- "continue" to see any. This should be fixed. */
- need_artificial_trap = 1;
+ expect ("ST\r");
}
else
{
- if (need_gi)
- {
- need_gi = 0;
- write (eb_desc, "gi\n", 3);
-
- /* Swallow the echo of "gi". */
- expect ("gi\r");
- }
- else
- {
- write (eb_desc, "GR\n", 3);
- /* Swallow the echo. */
- expect ("GR\r");
- }
+ printf_stdebug ("GO\r");
+ /* Swallow the echo. */
+ expect ("GO\r");
}
}
/* Wait until the remote machine stops, then return,
storing status in STATUS just as `wait' would. */
-int
-eb_wait (status)
+static int
+st2000_wait (status)
WAITTYPE *status;
{
- /* Strings to look for. '?' means match any single character.
- Note that with the algorithm we use, the initial character
- of the string cannot recur in the string, or we will not
- find some cases of the string in the input. */
-
- static char bpt[] = "Invalid interrupt taken - #0x50 - ";
- /* It would be tempting to look for "\n[__exit + 0x8]\n"
- but that requires loading symbols with "yc i" and even if
- we did do that we don't know that the file has symbols. */
- static char exitmsg[] = "\n@????????I JMPTI GR121,LR0";
+ /* FIXME --- USE A REAL STRING MATCHING ALGORITHM HERE!!! */
+
+ static char bpt[] = "dbug> ";
char *bp = bpt;
- char *ep = exitmsg;
/* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */
char swallowed[50];
@@ -548,13 +505,6 @@ eb_wait (status)
WSETEXIT ((*status), 0);
- if (need_artificial_trap != 0)
- {
- WSETSTOP ((*status), SIGTRAP);
- need_artificial_trap--;
- return 0;
- }
-
timeout = 0; /* Don't time out -- user program is running. */
while (1)
{
@@ -572,19 +522,6 @@ eb_wait (status)
else
bp = bpt;
- if (ch == *ep || *ep == '?')
- {
- ep++;
- if (*ep == '\0')
- break;
-
- if (!ch_handled)
- *swallowed_p++ = ch;
- ch_handled = 1;
- }
- else
- ep = exitmsg;
-
if (!ch_handled)
{
char *p;
@@ -597,8 +534,7 @@ eb_wait (status)
putc (ch, stdout);
}
}
- expect_prompt ();
- if (*bp== '\0')
+ if (*bp == '\000')
WSETSTOP ((*status), SIGTRAP);
else
WSETEXIT ((*status), 0);
@@ -607,142 +543,54 @@ eb_wait (status)
return 0;
}
-/* Return the name of register number REGNO
- in the form input and output by EBMON.
+/* Return the name of register number REGNO in the form input and output by
+ STDEBUG. Currently, REGISTER_NAMES just happens to contain exactly what
+ STDEBUG wants. Lets take advantage of that just as long as possible! */
- Returns a pointer to a static buffer containing the answer. */
static char *
get_reg_name (regno)
int regno;
{
- static char buf[80];
- if (regno >= GR96_REGNUM && regno < GR96_REGNUM + 32)
- sprintf (buf, "GR%03d", regno - GR96_REGNUM + 96);
- else if (regno >= LR0_REGNUM && regno < LR0_REGNUM + 128)
- sprintf (buf, "LR%03d", regno - LR0_REGNUM);
- else if (regno == Q_REGNUM)
- strcpy (buf, "SR131");
- else if (regno >= BP_REGNUM && regno <= CR_REGNUM)
- sprintf (buf, "SR%03d", regno - BP_REGNUM + 133);
- else if (regno == ALU_REGNUM)
- strcpy (buf, "SR132");
- else if (regno >= IPC_REGNUM && regno <= IPB_REGNUM)
- sprintf (buf, "SR%03d", regno - IPC_REGNUM + 128);
- else if (regno >= VAB_REGNUM && regno <= LRU_REGNUM)
- sprintf (buf, "SR%03d", regno - VAB_REGNUM);
- else if (regno == GR1_REGNUM)
- strcpy (buf, "GR001");
+ static char buf[50];
+ char *p, *b;
+
+ b = buf;
+
+ for (p = reg_names[regno]; *p; p++)
+ *b++ = toupper(*p);
+ *b = '\000';
+
return buf;
}
/* Read the remote registers into the block REGS. */
static void
-eb_fetch_registers ()
+st2000_fetch_registers ()
{
- int reg_index;
- int regnum_index;
- char tempbuf[10];
- int i;
-
-#if 0
- /* This should not be necessary, because one is supposed to read the
- registers only when the inferior is stopped (at least with
- ptrace() and why not make it the same for remote?). */
- /* ^A is the "normal character" used to make sure we are talking to EBMON
- and not to the program being debugged. */
- write (eb_desc, "\001\n");
- expect_prompt ();
-#endif
-
- write (eb_desc, "dw gr96,gr127\n", 14);
- for (reg_index = 96, regnum_index = GR96_REGNUM;
- reg_index < 128;
- reg_index += 4, regnum_index += 4)
- {
- sprintf (tempbuf, "GR%03d ", reg_index);
- expect (tempbuf);
- get_hex_regs (4, regnum_index);
- expect ("\n");
- }
-
- for (i = 0; i < 128; i += 32)
- {
- /* The PC has a tendency to hang if we get these
- all in one fell swoop ("dw lr0,lr127"). */
- sprintf (tempbuf, "dw lr%d\n", i);
- write (eb_desc, tempbuf, strlen (tempbuf));
- for (reg_index = i, regnum_index = LR0_REGNUM + i;
- reg_index < i + 32;
- reg_index += 4, regnum_index += 4)
- {
- sprintf (tempbuf, "LR%03d ", reg_index);
- expect (tempbuf);
- get_hex_regs (4, regnum_index);
- expect ("\n");
- }
- }
-
- write (eb_desc, "dw sr133,sr133\n", 15);
- expect ("SR133 ");
- get_hex_regs (1, BP_REGNUM);
- expect ("\n");
-
- write (eb_desc, "dw sr134,sr134\n", 15);
- expect ("SR134 ");
- get_hex_regs (1, FC_REGNUM);
- expect ("\n");
-
- write (eb_desc, "dw sr135,sr135\n", 15);
- expect ("SR135 ");
- get_hex_regs (1, CR_REGNUM);
- expect ("\n");
-
- write (eb_desc, "dw sr131,sr131\n", 15);
- expect ("SR131 ");
- get_hex_regs (1, Q_REGNUM);
- expect ("\n");
-
- write (eb_desc, "dw sr0,sr14\n", 12);
- for (reg_index = 0, regnum_index = VAB_REGNUM;
- regnum_index <= LRU_REGNUM;
- regnum_index += 4, reg_index += 4)
- {
- sprintf (tempbuf, "SR%03d ", reg_index);
- expect (tempbuf);
- get_hex_regs (reg_index == 12 ? 3 : 4, regnum_index);
- expect ("\n");
- }
+ int regno;
- /* There doesn't seem to be any way to get these. */
- {
- int val = -1;
- supply_register (FPE_REGNUM, &val);
- supply_register (INT_REGNUM, &val);
- supply_register (FPS_REGNUM, &val);
- supply_register (EXO_REGNUM, &val);
- }
+ /* Yeah yeah, I know this is horribly inefficient. But it isn't done
+ very often... I'll clean it up later. */
- write (eb_desc, "dw gr1,gr1\n", 11);
- expect ("GR001 ");
- get_hex_regs (1, GR1_REGNUM);
- expect_prompt ();
+ for (regno = 0; regno <= PC_REGNUM; regno++)
+ st2000_fetch_register(regno);
}
/* Fetch register REGNO, or all registers if REGNO is -1.
Returns errno value. */
-void
-eb_fetch_register (regno)
+static void
+st2000_fetch_register (regno)
int regno;
{
if (regno == -1)
- eb_fetch_registers ();
+ st2000_fetch_registers ();
else
{
char *name = get_reg_name (regno);
- fprintf (eb_stream, "dw %s,%s\n", name, name);
+ printf_stdebug ("DR %s\r", name);
expect (name);
- expect (" ");
+ expect (" : ");
get_hex_regs (1, regno);
expect_prompt ();
}
@@ -752,65 +600,31 @@ eb_fetch_register (regno)
/* Store the remote registers from the contents of the block REGS. */
static void
-eb_store_registers ()
+st2000_store_registers ()
{
- int i, j;
- fprintf (eb_stream, "s gr1,%x\n", read_register (GR1_REGNUM));
- expect_prompt ();
+ int regno;
- for (j = 0; j < 32; j += 16)
- {
- fprintf (eb_stream, "s gr%d,", j + 96);
- for (i = 0; i < 15; ++i)
- fprintf (eb_stream, "%x,", read_register (GR96_REGNUM + j + i));
- fprintf (eb_stream, "%x\n", read_register (GR96_REGNUM + j + 15));
- expect_prompt ();
- }
+ for (regno = 0; regno <= PC_REGNUM; regno++)
+ st2000_store_register(regno);
- for (j = 0; j < 128; j += 16)
- {
- fprintf (eb_stream, "s lr%d,", j);
- for (i = 0; i < 15; ++i)
- fprintf (eb_stream, "%x,", read_register (LR0_REGNUM + j + i));
- fprintf (eb_stream, "%x\n", read_register (LR0_REGNUM + j + 15));
- expect_prompt ();
- }
-
- fprintf (eb_stream, "s sr133,%x,%x,%x\n", read_register (BP_REGNUM),
- read_register (FC_REGNUM), read_register (CR_REGNUM));
- expect_prompt ();
- fprintf (eb_stream, "s sr131,%x\n", read_register (Q_REGNUM));
- expect_prompt ();
- fprintf (eb_stream, "s sr0,");
- for (i = 0; i < 11; ++i)
- fprintf (eb_stream, "%x,", read_register (VAB_REGNUM + i));
- fprintf (eb_stream, "%x\n", read_register (VAB_REGNUM + 11));
- expect_prompt ();
+ registers_changed ();
}
/* Store register REGNO, or all if REGNO == 0.
Return errno value. */
-int
-eb_store_register (regno)
+static void
+st2000_store_register (regno)
int regno;
{
if (regno == -1)
- eb_store_registers ();
+ st2000_store_registers ();
else
{
- char *name = get_reg_name (regno);
- fprintf (eb_stream, "s %s,%x\n", name, read_register (regno));
- /* Setting GR1 changes the numbers of all the locals, so
- invalidate the register cache. Do this *after* calling
- read_register, because we want read_register to return the
- value that write_register has just stuffed into the registers
- array, not the value of the register fetched from the
- inferior. */
- if (regno == GR1_REGNUM)
- registers_changed ();
+ printf_stdebug ("PR %s %x\r", get_reg_name (regno),
+ read_register (regno));
+
expect_prompt ();
}
- return 0;
}
/* Get ready to modify the registers array. On machines which store
@@ -819,64 +633,41 @@ eb_store_register (regno)
that registers contains all the registers from the program being
debugged. */
-void
-eb_prepare_to_store ()
+static void
+st2000_prepare_to_store ()
{
/* Do nothing, since we can store individual regs */
}
-
-/* FIXME-someday! Merge these two. */
-int
-eb_xfer_inferior_memory (memaddr, myaddr, len, write, target)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
- int write;
- struct target_ops *target; /* ignored */
-{
- if (write)
- return eb_write_inferior_memory (memaddr, myaddr, len);
- else
- return eb_read_inferior_memory (memaddr, myaddr, len);
-}
-
-void
-eb_files_info ()
+static void
+st2000_files_info ()
{
- printf ("\tAttached to %s at %d baud and running program %s.\n",
- dev_name, baudrate, prog_name);
+ printf ("\tAttached to %s at %d baud.\n",
+ dev_name, baudrate);
}
/* Copy LEN bytes of data from debugger memory at MYADDR
to inferior's memory at MEMADDR. Returns length moved. */
-int
-eb_write_inferior_memory (memaddr, myaddr, len)
+static int
+st2000_write_inferior_memory (memaddr, myaddr, len)
CORE_ADDR memaddr;
- char *myaddr;
+ unsigned char *myaddr;
int len;
{
int i;
for (i = 0; i < len; i++)
{
- if ((i % 16) == 0)
- fprintf (eb_stream, "sb %x,", memaddr + i);
- if ((i % 16) == 15 || i == len - 1)
- {
- fprintf (eb_stream, "%x\n", ((unsigned char *)myaddr)[i]);
- expect_prompt ();
- }
- else
- fprintf (eb_stream, "%x,", ((unsigned char *)myaddr)[i]);
+ printf_stdebug ("PM.B %x %x\r", memaddr + i, myaddr[i]);
+ expect_prompt ();
}
return len;
}
/* Read LEN bytes from inferior memory at MEMADDR. Put the result
at debugger address MYADDR. Returns length moved. */
-int
-eb_read_inferior_memory(memaddr, myaddr, len)
+static int
+st2000_read_inferior_memory(memaddr, myaddr, len)
CORE_ADDR memaddr;
char *myaddr;
int len;
@@ -895,10 +686,10 @@ eb_read_inferior_memory(memaddr, myaddr, len)
/* Note that this code works correctly if startaddr is just less
than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
thing). That is, something like
- eb_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
+ st2000_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
works--it never adds len to memaddr and gets 0. */
/* However, something like
- eb_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
+ st2000_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
doesn't need to work. Detect it and give up if there's an attempt
to do that. */
if (((memaddr - 1) + len) < memaddr) {
@@ -916,26 +707,8 @@ eb_read_inferior_memory(memaddr, myaddr, len)
if (len_this_pass > (len - count))
len_this_pass = (len - count);
- fprintf (eb_stream, "db %x,%x\n", startaddr,
- (startaddr - 1) + len_this_pass);
- expect ("\n");
-
- /* Look for 8 hex digits. */
- i = 0;
- while (1)
- {
- if (isxdigit (readchar ()))
- ++i;
- else
- {
- expect_prompt ();
- error ("Hex digit expected from remote system.");
- }
- if (i >= 8)
- break;
- }
-
- expect (" ");
+ printf_stdebug ("DI.L %x %x\r", startaddr, len_this_pass);
+ expect (": ");
for (i = 0; i < len_this_pass; i++)
get_hex_byte (&myaddr[count++]);
@@ -947,8 +720,23 @@ eb_read_inferior_memory(memaddr, myaddr, len)
return len;
}
+/* FIXME-someday! Merge these two. */
+static int
+st2000_xfer_inferior_memory (memaddr, myaddr, len, write, target)
+ CORE_ADDR memaddr;
+ char *myaddr;
+ int len;
+ int write;
+ struct target_ops *target; /* ignored */
+{
+ if (write)
+ return st2000_write_inferior_memory (memaddr, myaddr, len);
+ else
+ return st2000_read_inferior_memory (memaddr, myaddr, len);
+}
+
static void
-eb_kill (args, from_tty)
+st2000_kill (args, from_tty)
char *args;
int from_tty;
{
@@ -961,33 +749,81 @@ eb_kill (args, from_tty)
run again without a download. Don't leave it full of breakpoint
instructions. */
-void
-eb_mourn_inferior ()
+static void
+st2000_mourn_inferior ()
{
remove_breakpoints ();
generic_mourn_inferior (); /* Do all the proper things now */
}
+
+#define MAX_STDEBUG_BREAKPOINTS 16
+
+extern int memory_breakpoint_size;
+static CORE_ADDR breakaddr[MAX_STDEBUG_BREAKPOINTS] = {0};
+
+static int
+st2000_insert_breakpoint (addr, shadow)
+ CORE_ADDR addr;
+ char *shadow;
+{
+ int i;
+
+ for (i = 0; i <= MAX_STDEBUG_BREAKPOINTS; i++)
+ if (breakaddr[i] == 0)
+ {
+ breakaddr[i] = addr;
+
+ st2000_read_inferior_memory(addr, shadow, memory_breakpoint_size);
+ printf_stdebug("BR %x H\r", addr);
+ expect_prompt();
+ return 0;
+ }
+
+ fprintf(stderr, "Too many breakpoints (> 16) for STDBUG\n");
+ return 1;
+}
+
+static int
+st2000_remove_breakpoint (addr, shadow)
+ CORE_ADDR addr;
+ char *shadow;
+{
+ int i;
+
+ for (i = 0; i < MAX_STDEBUG_BREAKPOINTS; i++)
+ if (breakaddr[i] == addr)
+ {
+ breakaddr[i] = 0;
+
+ printf_stdebug("CB %d\r", i);
+ expect_prompt();
+ return 0;
+ }
+
+ fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
+ return 1;
+}
+
/* Define the target subroutine names */
-struct target_ops eb_ops = {
- "amd-eb", "Remote serial AMD EBMON target",
- "Use a remote computer running EBMON connected by a serial line.\n\
+static struct target_ops st2000_ops = {
+ "st2000", "Remote serial Tandem ST2000 target",
+ "Use a remote computer running STDEBUG 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, and the filename of the\n\
-executable as it exists on the remote computer. For example,\n\
- target amd-eb /dev/ttya 9600 demo",
- eb_open, eb_close,
- 0, eb_detach, eb_resume, eb_wait,
- eb_fetch_register, eb_store_register,
- eb_prepare_to_store, 0, 0, /* conv_to, conv_from */
- eb_xfer_inferior_memory, eb_files_info,
- 0, 0, /* Breakpoints */
+the speed to connect at in bits per second.",
+ st2000_open, st2000_close,
+ 0, st2000_detach, st2000_resume, st2000_wait,
+ st2000_fetch_register, st2000_store_register,
+ st2000_prepare_to_store, 0, 0, /* conv_to, conv_from */
+ st2000_xfer_inferior_memory, st2000_files_info,
+ st2000_insert_breakpoint, st2000_remove_breakpoint, /* Breakpoints */
0, 0, 0, 0, 0, /* Terminal handling */
- eb_kill,
+ st2000_kill,
0, /* load */
0, /* lookup_symbol */
- eb_create_inferior,
- eb_mourn_inferior,
+ st2000_create_inferior,
+ st2000_mourn_inferior,
process_stratum, 0, /* next */
1, 1, 1, 1, 1, /* all mem, mem, stack, regs, exec */
0, 0, /* Section pointers */
@@ -995,7 +831,7 @@ executable as it exists on the remote computer. For example,\n\
};
void
-_initialize_remote_eb ()
+_initialize_remote_st2000 ()
{
- add_target (&eb_ops);
+ add_target (&st2000_ops);
}