aboutsummaryrefslogtreecommitdiff
path: root/gdb/remote-e7000.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/remote-e7000.c')
-rw-r--r--gdb/remote-e7000.c397
1 files changed, 292 insertions, 105 deletions
diff --git a/gdb/remote-e7000.c b/gdb/remote-e7000.c
index 6951804..644650e 100644
--- a/gdb/remote-e7000.c
+++ b/gdb/remote-e7000.c
@@ -1,6 +1,8 @@
-/* Remote debugging interface for Hitachi E7000 ICE, for GDB.
+/* Remote debugging interface for Hitachi E7000 ICE, for GDB
Copyright 1993 Free Software Foundation, Inc.
- Contributed by Cygnus Support. Written by Steve Chamberlain for Cygnus.
+ Contributed by Cygnus Support.
+
+ Written by Steve Chamberlain for Cygnus Support.
This file is part of GDB.
@@ -52,7 +54,7 @@ extern struct target_ops e7000_ops; /* Forward declaration */
char *ENQSTRING = "\005";
int echo;
-static int echo_index;
+int ctrl_c;
static void e7000_close ();
static void e7000_fetch_register ();
static void e7000_store_register ();
@@ -66,7 +68,7 @@ static serial_t e7000_desc;
/* Send data to e7000debug. Works just like printf. */
-
+#if 0
static void
printf_e7000debug (va_alist)
va_dcl
@@ -80,6 +82,14 @@ printf_e7000debug (va_alist)
pattern = va_arg (args, char *);
vsprintf (buf, pattern, args);
+#else
+
+static void
+printf_e7000debug(a,b,c,d,e)
+ {
+ char buf[200];
+ sprintf(buf, a,b,c,d,e);
+#endif
if (SERIAL_WRITE (e7000_desc, buf, strlen (buf)))
fprintf (stderr, "SERIAL_WRITE failed: %s\n", safe_strerror (errno));
@@ -125,6 +135,7 @@ readchar (timeout)
return c;
}
+
/* Scan input from the remote system, until STRING is found. If DISCARD is
non-zero, then discard non-matching input, else print it out.
Let the user break out immediately. */
@@ -135,16 +146,29 @@ expect (string)
char *p = string;
int c;
- immediate_quit = 1;
while (1)
{
c = readchar (timeout);
+
+ notice_quit ();
+ if (quit_flag == 1)
+ {
+ if (ctrl_c) {
+ putchar_e7000(CTRLC);
+ ctrl_c -- ;
+ }
+ else
+ {
+ quit();
+ }
+ }
+
if (c == SERIAL_ERROR)
{
error ("Serial communication error");
}
- if (echo_index)
+ if (echo)
{
if (c != '\r')
putchar (c);
@@ -154,7 +178,6 @@ expect (string)
{
if (*p == '\0')
{
- immediate_quit = 0;
return;
}
}
@@ -182,21 +205,11 @@ expect (string)
static void
expect_prompt ()
{
-#if defined (LOG_FILE)
- /* This is a convenient place to do this. The idea is to do it often
- enough that we never lose much data if we terminate abnormally. */
- fflush (log_file);
-#endif
expect (":");
}
static void
expect_full_prompt ()
{
-#if defined (LOG_FILE)
- /* This is a convenient place to do this. The idea is to do it often
- enough that we never lose much data if we terminate abnormally. */
- fflush (log_file);
-#endif
expect ("\n:");
}
@@ -363,7 +376,6 @@ e7000_ftp (args, from_tty)
{
int oldtimeout = timeout;
timeout = 10;
- echo_index++;
printf_e7000debug ("ftp %s\r", machine);
expect (" Username : ");
printf_e7000debug ("%s\r", user);
@@ -378,7 +390,6 @@ e7000_ftp (args, from_tty)
expect ("FTP>");
printf_e7000debug ("bye\r");
expect (":");
- echo_index--;
timeout = oldtimeout;
}
@@ -420,6 +431,7 @@ or \t\ttarget e7000 <host>[:<port>]\n");
/* Hello? Are you there? */
sync = 0;
+ putchar_e7000 (CTRLC);
while (!sync)
{
int c;
@@ -454,6 +466,9 @@ or \t\ttarget e7000 <host>[:<port>]\n");
printf_filtered ("Remote %s connected to %s\n", target_shortname,
dev_name);
+#ifdef GDB_TARGET_IS_H8300
+ h8300hmode = 1;
+#endif
}
/* Close out all files and local state before this target loses control. */
@@ -499,25 +514,35 @@ e7000_resume (pid, step, sig)
/* Read the remote registers into the block REGS.
- A reg dump looks like:
+ For the H8/300 a register dump looks like:
+
+ PC=00021A CCR=80:I*******
+ ER0 - ER3 0000000A 0000002E 0000002E 00000000
+ ER4 - ER7 00000000 00000000 00000000 00FFEFF6
+ 000218 MOV.B R1L,R2L
+ STEP NORMAL END or
+ BREAK POINT
*/
#ifdef GDB_TARGET_IS_H8300
char *want = "\n\
PC=%p CCR=%c\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 = "%p CCR=%c\n\
+ ER0 - ER3 %0 %1 %2 %3\n\
+ ER4 - ER7 %4 %5 %6 %7";
+
#endif
#ifdef GDB_TARGET_IS_SH
-char *want = "\n\PC=%16 SR=%22\n\
+char *want = "\n PC=%16 SR=%22\n\
PR=%17 GBR=%18 VBR=%19\n\
MACH=%20 MACL=%21\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\
PR=%17 GBR=%18 VBR=%19\n\
@@ -577,7 +602,7 @@ fetch_regs_from_dump (nextchar, want)
break;
case ' ':
- while (thischar == ' ' || thischar == '\t')
+ while (thischar == ' ' || thischar == '\t' || thischar == '\r' || thischar == '\n')
thischar = nextchar();
want++;
break;
@@ -856,14 +881,14 @@ write_large (memaddr, myaddr, len)
int len;
{
int i;
+ int c;
#define maxstride 128
int stride;
- printf_e7000debug ("il ;s:s\r");
+ printf_e7000debug ("IL ;S:FK\r");
expect (ENQSTRING);
putchar_e7000 (ACK);
- expect ("LO s\r");
-
+ expect ("LO FK\r");
for (i = 0; i < len; i += stride)
{
char compose[maxstride * 2 + 50];
@@ -888,8 +913,8 @@ write_large (memaddr, myaddr, len)
}
else
alen = 2;
- compose[where++] = alen - 1 + '0'; /* insert type */
- check_sum += stickbyte (compose + where, alen + stride + 1); /* Insert length */
+ compose[where++] = alen - 1 + '0'; /* insert type */
+ check_sum += stickbyte (compose + where, alen + stride + 1); /* Insert length */
where += 2;
while (alen > 0)
{
@@ -908,23 +933,34 @@ write_large (memaddr, myaddr, len)
where += 2;
compose[where++] = '\r';
- SERIAL_WRITE (e7000_desc, compose, where);
- j = SERIAL_READCHAR (e7000_desc, 0);
- if (j == SERIAL_TIMEOUT)
- {
- /* This is ok - nothing there */
- }
- else if (j == ENQ)
- {
- /* Hmm, it's trying to tell us something */
- expect (":");
- error ("Error writing memory");
- }
- else
+ compose[where++] = '\n';
+ compose[where++] = 0;
+ {
+ char *z;
+ for (z = compose; *z; z++) ;
{
- printf ("Whats this %d\n", j);
+ SERIAL_WRITE (e7000_desc, compose, where);
+ j = SERIAL_READCHAR (e7000_desc, 0);
+ if (j == SERIAL_TIMEOUT)
+ {
+ /* This is ok - nothing there */
+ }
+ else if (j == ENQ)
+ {
+ /* Hmm, it's trying to tell us something */
+ expect (":");
+ error ("Error writing memory");
+ }
+ else
+ {
+ printf ("@%d}@", j);
+ while ((j = SERIAL_READCHAR(e7000_desc,0)) > 0)
+ {
+ printf ("@{%d}@",j);
+ }
+ }
}
-
+ }
}
/* Send the trailer record */
write_e7000 ("S70500000000FA\r");
@@ -957,13 +993,6 @@ e7000_write_inferior_memory (memaddr, myaddr, len)
}
}
-/* Read LEN bytes from inferior memory at MEMADDR. Put the result
- at debugger address MYADDR. Returns length moved.
-
- Done by requesting an srecord dump from the E7000.
- */
-
-
/* Read LEN bytes from inferior memory at MEMADDR. Put the result
at debugger address MYADDR. Returns length moved.
@@ -1257,8 +1286,7 @@ e7000_insert_breakpoint (addr, shadow)
unsigned char *shadow;
{
int i;
- static char nop[2] =
- {0x20, 0x0b};
+ static char nop[2] = NOP;
for (i = 0; i <= MAX_E7000DEBUG_BREAKPOINTS; i++)
if (breakaddr[i] == 0)
@@ -1318,9 +1346,11 @@ e7000_command (args, fromtty)
{
printf_e7000debug ("%s\r", args);
}
- echo_index++;
+ echo++;
+ ctrl_c = 2;
expect_full_prompt ();
- echo_index--;
+ echo--;
+ ctrl_c = 0;
printf_unfiltered ("\n");
}
@@ -1329,7 +1359,7 @@ e7000_load (args, fromtty)
char *args;
int fromtty;
{
- load_target_image (args, fromtty);
+ gr_load_image (args, fromtty);
}
static void
@@ -1339,9 +1369,15 @@ e7000_drain (args, fromtty)
{
int c;
-
- while ((c = SERIAL_READCHAR (e7000_desc, 2) != SERIAL_TIMEOUT))
+ printf_e7000debug("end\r");
+ putchar_e7000 (CTRLC);
+ while ((c = SERIAL_READCHAR (e7000_desc, 1) != SERIAL_TIMEOUT))
{
+ if(quit_flag)
+ {
+ putchar_e7000(CTRLC);
+ quit_flag = 0;
+ }
if (c > ' ' && c < 127)
printf ("%c", c & 0xff);
else
@@ -1352,8 +1388,152 @@ e7000_drain (args, fromtty)
e7000_noecho ()
{
echo = !echo;
+ if (echo)
+ printf_filtered ("Snoop enabled\n");
+ else
+ printf_filtered ("Snoop disabled\n");
+
+}
+
+#define NITEMS 3
+static int
+why_stop ()
+{
+ static char *strings[NITEMS] =
+ {
+ "STEP NORMAL",
+ "BREAK POINT",
+ "BREAK KEY",
+ };
+ char *p[NITEMS];
+ int c;
+ p[0] = strings[0];
+ p[1] = strings[1];
+ p[2] = strings[2];
+
+ c = gch();
+ while (1)
+ {
+ int i;
+ for (i = 0; i < NITEMS; i++)
+ {
+ if (c == *(p[i]))
+ {
+ p[i]++;
+ if (*(p[i]) == 0)
+ {
+ /* found one of the choices */
+ return i;
+ }
+ }
+ else {
+ p[i] = strings[i];
+ }
+ }
+
+ c = gch();
+ }
+}
+/* Suck characters, if a string match, then return the strings index
+ otherwise echo them */
+int
+expect_n ( strings)
+char **strings;
+{
+ char *(ptr[10]);
+ int n;
+ int c;
+ char saveaway[100];
+ char *buffer = saveaway;
+ /* Count number of expect strings */
+
+ for (n =0; strings[n]; n++)
+ {
+ ptr[n] = strings[n];
+ }
+
+ while (1) {
+ int i;
+ int gotone = 0;
+
+ c = SERIAL_READCHAR (e7000_desc, 1);
+ if (c == SERIAL_TIMEOUT) {
+ printf_unfiltered ("[waiting for e7000...]\n");
+ }
+#ifdef __GO32__
+ if (kbhit())
+ {
+ int k = getkey();
+ if (k == 1)
+ quit_flag = 1;
+ }
+#endif
+
+ if (quit_flag)
+ {
+ putchar_e7000 (CTRLC); /* interrupt the running program */
+ quit_flag = 0;
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ if (c == ptr[i][0])
+ {
+ ptr[i]++;
+ if (ptr[i][0] == 0)
+ {
+ /* Gone all the way */
+ return i;
+ }
+ gotone = 1;
+ }
+ else
+ {
+ ptr[i] = strings[i];
+ }
+ }
+
+
+ if (gotone)
+ {
+ /* Save it up incase we find that there was no match */
+ *buffer ++ = c;
+ }
+ else
+ {
+ if (buffer != saveaway)
+ {
+ *buffer++ = 0;
+ printf(buffer);
+ buffer = saveaway;
+ }
+ if (c != SERIAL_TIMEOUT) {
+ putchar (c);
+ fflush(stdout);
+ }
+ }
+ }
}
+/* We subtract two from the pc here rather than use DECR_PC_AFTER_BREAK
+ since the e7000 doesn't always add two to the pc, and the simulators never do. */
+
+static void
+sub2_from_pc()
+{
+ char buf[4];
+ store_signed_integer (buf,
+ REGISTER_RAW_SIZE(PC_REGNUM),
+ read_register (PC_REGNUM) -2);
+ supply_register (PC_REGNUM, buf);
+ printf_e7000debug (".PC %x\r", read_register (PC_REGNUM));
+}
+#define WAS_SLEEP 0
+#define WAS_INT 1
+#define WAS_RUNNING 2
+#define WAS_OTHER 3
+static char *estrings[] = { "** SLEEP", "BREAK !", "** PC", "PC", 0};
+
/* Wait until the remote machine stops, then return,
storing status in STATUS just as `wait' would. */
@@ -1363,8 +1543,12 @@ e7000_wait (pid, status)
WAITTYPE *status;
{
int c;
+ int reset_pc;
int regno;
+ int running_count = 0;
+ int had_sleep = 0;
int loop = 1;
+ char *reg;
int time = 0;
WSETSTOP ((*status), 0);
/* Then echo chars until PC= string seen */
@@ -1372,51 +1556,32 @@ e7000_wait (pid, status)
gch (); /* and space */
while (loop)
{
- c = SERIAL_READCHAR (e7000_desc, 1);
- if (c < 0)
- {
- time++;
- if (time == 5)
- {
- printf_unfiltered ("[waiting for e7000..]\n");
- time = 0;
- }
- }
- if (quit_flag)
- {
- quit_flag = 0;
- putchar_e7000 (CTRLC); /* interrupt the running program */
- }
- if (c == 'P')
- {
- c = SERIAL_READCHAR (e7000_desc, 1);
- if (c == 'C')
- {
- c = SERIAL_READCHAR (e7000_desc, 1);
- if (c == '=')
- {
- /* Got break */
- loop = 0;
- }
- else
- {
- printf ("PC");
- }
- }
- else
- {
- printf ("P");
- }
- }
- else
- {
- if (c > 0)
+ switch (expect_n(estrings))
+ {
+ case WAS_OTHER:
+ /* how did this happen ? */
+ loop =0;
+ break;
+ case WAS_SLEEP:
+ had_sleep = 1;
+ putchar_e7000 (CTRLC);
+ loop = 0;
+ break;
+ case WAS_INT:
+ loop = 0;
+ break;
+ case WAS_RUNNING:
+ running_count++;
+ if (running_count == 20)
{
- putchar (c);
- fflush (stdout);
+ printf_unfiltered ("[running...]\n");
+ running_count = 0;
}
+ break;
}
}
+ /* Skip till the PC=*/
+ expect("=");
fetch_regs_from_dump (gch, want_nopc);
/* And supply the extra ones the simulator uses */
@@ -1426,9 +1591,32 @@ e7000_wait (pid, status)
supply_register (regno, (char *) &buf);
}
+ reset_pc = why_stop ();
expect_full_prompt ();
- WSETSTOP ((*status), SIGTRAP);
+ switch (reset_pc)
+ {
+ case 1: /* Breakpoint */
+
+ WSETSTOP ((*status), SIGTRAP);
+ break;
+ case 0:
+ /* Single step */
+ WSETSTOP ((*status), SIGTRAP);
+ break;
+ case 2:
+ /* Interrupt */
+ if (had_sleep)
+ {
+ sub2_from_pc();
+ WSETSTOP ((*status), SIGTRAP);
+ }
+ else
+ {
+ WSETSTOP ((*status), SIGINT);
+ }
+ break;
+ }
return 0;
}
@@ -1456,7 +1644,7 @@ target e7000 foobar",
e7000_prepare_to_store,
e7000_xfer_inferior_memory,
e7000_files_info,
- e7000_insert_breakpoint,
+0,0,/* e7000_insert_breakpoint,
e7000_remove_breakpoint, /* Breakpoints */
0,
0,
@@ -1497,6 +1685,5 @@ _initialize_remote_e7000 ()
add_com ("drain", class_obscure, e7000_drain,
"Drain pending e7000 text buffers.");
- add_com ("echo", class_obscure, e7000_noecho, "Toggle monitor echo.");
-
+ add_com ("snoop", class_obscure, e7000_noecho, "Toggle monitor echo.");
}