* remote-hms.c (readchar, hms_open, hms_fetch_register): Made more robust.

(remove_commands, add_commands): Add/remove hms-drain when target
	is connected.
This commit is contained in:
Steve Chamberlain 1994-02-12 05:52:11 +00:00
parent 68ac42f696
commit 3b5442f9c8
2 changed files with 188 additions and 126 deletions

View file

@ -1,3 +1,9 @@
Fri Feb 11 21:47:24 1994 Steve Chamberlain (sac@sphagnum.cygnus.com)
* remote-hms.c (readchar, hms_open, hms_fetch_register): Made more robust.
(remove_commands, add_commands): Add/remove hms-drain when target
is connected.
Fri Feb 11 16:11:38 1994 Stu Grossman (grossman at cygnus.com) Fri Feb 11 16:11:38 1994 Stu Grossman (grossman at cygnus.com)
* configure.in: Add Lynx/rs6000 support. * configure.in: Add Lynx/rs6000 support.

View file

@ -1,5 +1,5 @@
/* Remote debugging interface for Hitachi HMS Monitor Version 1.0 /* Remote debugging interface for Hitachi HMS Monitor Version 1.0
Copyright 1992 Free Software Foundation, Inc. Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
Contributed by Cygnus Support. Written by Steve Chamberlain Contributed by Cygnus Support. Written by Steve Chamberlain
(sac@cygnus.com). (sac@cygnus.com).
@ -47,6 +47,9 @@ static void hms_close ();
static int hms_clear_breakpoints (); static int hms_clear_breakpoints ();
extern struct target_ops hms_ops; extern struct target_ops hms_ops;
static void hms_drain ();
static void add_commands ();
static void remove_commands ();
static int quiet = 1; static int quiet = 1;
@ -258,7 +261,14 @@ readchar ()
buf = SERIAL_READCHAR (desc, timeout); buf = SERIAL_READCHAR (desc, timeout);
if (buf == SERIAL_TIMEOUT) if (buf == SERIAL_TIMEOUT)
error ("Timeout reading from remote system."); {
hms_write (".\r\n", 3);
error ("Timeout reading from remote system.");
}
if (buf == SERIAL_ERROR)
{
error ("Serial port error!");
}
if (!quiet) if (!quiet)
printf_unfiltered ("%c", buf); printf_unfiltered ("%c", buf);
@ -544,7 +554,7 @@ is_baudrate_right ()
/* Put this port into NORMAL mode, send the 'normal' character */ /* Put this port into NORMAL mode, send the 'normal' character */
hms_write ("\001", 1); /* Control A */ hms_write ("\001", 1); /* Control A */
hms_write ("\r", 1); /* Cr */ hms_write ("\r\n", 2); /* Cr */
while (1) while (1)
{ {
@ -594,13 +604,15 @@ hms_open (name, from_tty)
dcache_init (); dcache_init ();
/* Hello? Are you there? */ /* Hello? Are you there? */
SERIAL_WRITE (desc, "\r", 1); SERIAL_WRITE (desc, "\r\n", 2);
expect_prompt (); expect_prompt ();
/* Clear any break points */ /* Clear any break points */
hms_clear_breakpoints (); hms_clear_breakpoints ();
printf_filtered ("Connected to remote board running HMS monitor.\n"); printf_filtered ("Connected to remote board running HMS monitor.\n");
add_commands ();
hms_drain ();
} }
/* Close out all files and local state before this target loses control. */ /* Close out all files and local state before this target loses control. */
@ -610,20 +622,19 @@ hms_close (quitting)
int quitting; int quitting;
{ {
/* Clear any break points */ /* Clear any break points */
remove_commands ();
hms_clear_breakpoints (); hms_clear_breakpoints ();
sleep (1); /* Let any output make it all the way back */ sleep (1); /* Let any output make it all the way back */
if (is_open) if (is_open)
{ {
SERIAL_WRITE (desc, "R\r", 2); SERIAL_WRITE (desc, "R\r\n", 3);
SERIAL_CLOSE (desc); SERIAL_CLOSE (desc);
} }
is_open = 0; is_open = 0;
} }
/* Terminate the open connection to the remote debugger. /* Terminate the open connection to the remote debugger. Use this
Use this when you want to detach and do something else when you want to detach and do something else with your gdb. */ void
with your gdb. */
void
hms_detach (args, from_tty) hms_detach (args, from_tty)
char *args; char *args;
int from_tty; int from_tty;
@ -633,9 +644,11 @@ hms_detach (args, from_tty)
hms_clear_breakpoints (); hms_clear_breakpoints ();
} }
pop_target (); /* calls hms_close to do the real work */ pop_target (); /* calls hms_close to do the real work
*/
if (from_tty) if (from_tty)
printf_filtered ("Ending remote %s debugging\n", target_shortname); printf_filtered ("Ending remote %s debugging\n",
target_shortname);
} }
/* Tell the remote machine to resume. */ /* Tell the remote machine to resume. */
@ -643,7 +656,8 @@ hms_detach (args, from_tty)
void void
hms_resume (pid, step, sig) hms_resume (pid, step, sig)
int pid, step; int pid, step;
enum target_signal sig; enum target_signal
sig;
{ {
dcache_flush (); dcache_flush ();
@ -653,8 +667,8 @@ hms_resume (pid, step, sig)
expect ("Step>"); expect ("Step>");
/* Force the next hms_wait to return a trap. Not doing anything /* Force the next hms_wait to return a trap. Not doing anything
about I/O from the target means that the user has to type about I/O from the target means that the user has to type "continue"
"continue" to see any. FIXME, this should be fixed. */ to see any. FIXME, this should be fixed. */
need_artificial_trap = 1; need_artificial_trap = 1;
} }
else else
@ -664,29 +678,30 @@ hms_resume (pid, step, sig)
} }
} }
/* Wait until the remote machine stops, then return, /* Wait until the remote machine stops, then return, storing status in
storing status in STATUS just as `wait' would. */ STATUS just as `wait' would. */
int int
hms_wait (pid, status) hms_wait (pid, status)
int pid; int pid;
struct target_waitstatus *status; struct target_waitstatus *status;
{ {
/* Strings to look for. '?' means match any single character. /* Strings to look for. '?' means match any single character. Note
Note that with the algorithm we use, the initial character that with the algorithm we use, the initial character of the string
of the string cannot recur in the string, or we will not cannot recur in the string, or we will not find some cases of the
find some cases of the string in the input. */ string in the input. */
static char bpt[] = "At breakpoint:"; static char bpt[] = "At breakpoint:";
/* It would be tempting to look for "\n[__exit + 0x8]\n" /* It would be tempting to look for "\n[__exit + 0x8]\n" but that
but that requires loading symbols with "yc i" and even if requires loading symbols with "yc i" and even if we did do that we
we did do that we don't know that the file has symbols. */ don't know that the file has symbols. */
static char exitmsg[] = "HMS>"; static char exitmsg[] = "HMS>";
char *bp = bpt; char *bp = bpt;
char *ep = exitmsg; char *ep = exitmsg;
/* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars. */ /* Large enough for either sizeof (bpt) or sizeof (exitmsg) chars.
*/
char swallowed[50]; char swallowed[50];
/* Current position in swallowed. */ /* Current position in swallowed. */
@ -695,7 +710,8 @@ hms_wait (pid, status)
int ch; int ch;
int ch_handled; int ch_handled;
int old_timeout = timeout; int old_timeout = timeout;
int old_immediate_quit = immediate_quit; int
old_immediate_quit = immediate_quit;
int swallowed_cr = 0; int swallowed_cr = 0;
status->kind = TARGET_WAITKIND_EXITED; status->kind = TARGET_WAITKIND_EXITED;
@ -703,13 +719,15 @@ hms_wait (pid, status)
if (need_artificial_trap != 0) if (need_artificial_trap != 0)
{ {
status->kind = TARGET_WAITKIND_STOPPED; status->kind =
TARGET_WAITKIND_STOPPED;
status->value.sig = TARGET_SIGNAL_TRAP; status->value.sig = TARGET_SIGNAL_TRAP;
need_artificial_trap--; need_artificial_trap--;
return 0; return 0;
} }
timeout = -1; /* Don't time out -- user program is running. */ timeout = -1; /* Don't time out -- user program is running.
*/
immediate_quit = 1; /* Helps ability to QUIT */ immediate_quit = 1; /* Helps ability to QUIT */
while (1) while (1)
{ {
@ -729,16 +747,18 @@ hms_wait (pid, status)
{ {
bp = bpt; bp = bpt;
} }
if (ch == *ep || *ep == '?') if
{ (ch == *ep || *ep == '?')
ep++; {
if (*ep == '\0') ep++;
break; if (*ep == '\0')
break;
if (!ch_handled) if (!ch_handled)
*swallowed_p++ = ch; *swallowed_p++ = ch;
ch_handled = 1; ch_handled =
} 1;
}
else else
{ {
ep = exitmsg; ep = exitmsg;
@ -771,28 +791,32 @@ hms_wait (pid, status)
else else
{ {
status->kind = TARGET_WAITKIND_EXITED; status->kind = TARGET_WAITKIND_EXITED;
status->value.integer = TARGET_SIGNAL_STOP; status->value.integer =
TARGET_SIGNAL_STOP;
} }
timeout = old_timeout; timeout = old_timeout;
immediate_quit = old_immediate_quit; immediate_quit = old_immediate_quit;
return 0; return
0;
} }
/* Return the name of register number REGNO /* Return the name of register number REGNO in the form input and
in the form input and output by hms. output by hms.
Returns a pointer to a static buffer containing the answer. */ Returns a pointer to a static buffer containing the answer. */
static char * static char *
get_reg_name (regno) get_reg_name (regno)
int regno; int regno;
{ {
static char *rn[] = REGISTER_NAMES; static char *rn[] =
REGISTER_NAMES;
return rn[regno]; return rn[regno];
} }
/* Read the remote registers. */ /* Read the remote registers. */
static int static int
gethex (length, start, ok) gethex (length, start, ok)
unsigned int length; unsigned int length;
@ -808,14 +832,16 @@ gethex (length, start, ok)
{ {
result += *start - 'a' + 10; result += *start - 'a' + 10;
} }
else if (*start >= 'A' && *start <= 'F') else if (*start >= 'A' &&
*start <= 'F')
{ {
result += *start - 'A' + 10; result += *start - 'A' + 10;
} }
else if (*start >= '0' && *start <= '9') else if
{ (*start >= '0' && *start <= '9')
result += *start - '0'; {
} result += *start - '0';
}
else else
*ok = 0; *ok = 0;
start++; start++;
@ -825,7 +851,8 @@ gethex (length, start, ok)
} }
static int static int
timed_read (buf, n, timeout) timed_read (buf, n, timeout)
char *buf; char
*buf;
{ {
int i; int i;
@ -853,17 +880,21 @@ hms_write (a, l)
SERIAL_WRITE (desc, a, l); SERIAL_WRITE (desc, a, l);
if (!quiet) if (!quiet)
for (i = 0; i < l; i++) {
{ printf_unfiltered ("<");
printf_unfiltered ("%c", a[i]); for (i = 0; i < l; i++)
} {
printf_unfiltered ("%c", a[i]);
}
printf_unfiltered (">");
}
} }
hms_write_cr (s) hms_write_cr (s)
char *s; char *s;
{ {
hms_write (s, strlen (s)); hms_write (s, strlen (s));
hms_write ("\r", 1); hms_write ("\r\n", 2);
} }
#ifdef GDB_TARGET_IS_H8500 #ifdef GDB_TARGET_IS_H8500
@ -878,23 +909,23 @@ HMS>
*/ */
supply_val(n, size, ptr, segptr) supply_val (n, size, ptr, segptr)
int n; int n;
int size; int size;
char *ptr; char *ptr;
char *segptr; char *segptr;
{ {
int ok; int ok;
char raw[4]; char raw[4];
switch (size) switch (size)
{ {
case 2: case 2:
raw[0] = gethex(2, ptr, &ok); raw[0] = gethex (2, ptr, &ok);
raw[1] = gethex(2, ptr+2, &ok); raw[1] = gethex (2, ptr + 2, &ok);
supply_register (n, raw); supply_register (n, raw);
break; break;
case 1: case 1:
raw[0] = gethex(2,ptr,&ok); raw[0] = gethex (2, ptr, &ok);
supply_register (n, raw); supply_register (n, raw);
break; break;
case 4: case 4:
@ -902,9 +933,9 @@ char *segptr;
int v = gethex (4, ptr, &ok); int v = gethex (4, ptr, &ok);
v |= gethex (2, segptr, &ok) << 16; v |= gethex (2, segptr, &ok) << 16;
raw[0] = 0; raw[0] = 0;
raw[1] = (v>>16) & 0xff ; raw[1] = (v >> 16) & 0xff;
raw[2] = (v>>8) & 0xff ; raw[2] = (v >> 8) & 0xff;
raw[3] = (v>>0) & 0xff ; raw[3] = (v >> 0) & 0xff;
supply_register (n, raw); supply_register (n, raw);
} }
} }
@ -927,8 +958,8 @@ hms_fetch_register (dummy)
{ {
hms_write_cr ("r"); hms_write_cr ("r");
expect("r"); expect ("r");
s = timed_read (linebuf+1, REGREPLY_SIZE, 1); s = timed_read (linebuf + 1, REGREPLY_SIZE, 1);
linebuf[REGREPLY_SIZE] = 0; linebuf[REGREPLY_SIZE] = 0;
gottok = 0; gottok = 0;
@ -949,36 +980,37 @@ hms_fetch_register (dummy)
---6---------7---------8---------9--------10---- ---6---------7---------8---------9--------10----
789012345678901234567890123456789012345678901234 789012345678901234567890123456789012345678901234
R0-R7: FF5A 0001 F4FE F500 0000 F528 F528 F4EE** R0-R7: FF5A 0001 F4FE F500 0000 F528 F528 F4EE**
56789 56789
HMS> HMS>
*/ */
gottok = 1; gottok = 1;
supply_val(PC_REGNUM, 4, linebuf+6, linebuf+29);
supply_val(CCR_REGNUM, 2, linebuf+14); supply_val (PC_REGNUM, 4, linebuf + 6, linebuf + 29);
supply_val(SEG_C_REGNUM, 1, linebuf+29);
supply_val(SEG_D_REGNUM, 1, linebuf+35); supply_val (CCR_REGNUM, 2, linebuf + 14);
supply_val(SEG_E_REGNUM, 1, linebuf+41); supply_val (SEG_C_REGNUM, 1, linebuf + 29);
supply_val(SEG_T_REGNUM, 1, linebuf+47); supply_val (SEG_D_REGNUM, 1, linebuf + 35);
supply_val (SEG_E_REGNUM, 1, linebuf + 41);
supply_val (SEG_T_REGNUM, 1, linebuf + 47);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
static int sr[8] = { 35,35,35,35, static int sr[8] =
41,41,47,47}; {35, 35, 35, 35,
41, 41, 47, 47};
char raw[4]; char raw[4];
char *src = linebuf + 64 + 5 * i; char *src = linebuf + 64 + 5 * i;
char *segsrc = linebuf + sr[i]; char *segsrc = linebuf + sr[i];
supply_val(R0_REGNUM + i, 2, src); supply_val (R0_REGNUM + i, 2, src);
supply_val(PR0_REGNUM + i, 4, src, segsrc); supply_val (PR0_REGNUM + i, 4, src, segsrc);
} }
} }
if (!gottok) if (!gottok)
{ {
hms_write_cr (""); hms_write_cr ("");
expect("HMS>"); expect ("HMS>");
} }
} }
while (!gottok); while (!gottok);
@ -1002,9 +1034,14 @@ hms_fetch_register (dummy)
do do
{ {
hms_write_cr ("r"); hms_write_cr ("r");
s = timed_read (linebuf, REGREPLY_SIZE, 1);
s = timed_read (linebuf, 1, 1);
while (linebuf[0] != 'r')
s = timed_read (linebuf, 1, 1);
s = timed_read (linebuf + 1, REGREPLY_SIZE - 1, 1);
linebuf[REGREPLY_SIZE] = 0; linebuf[REGREPLY_SIZE] = 0;
gottok = 0; gottok = 0;
@ -1060,12 +1097,16 @@ hms_store_register (regno)
{ {
char *name = get_reg_name (regno); char *name = get_reg_name (regno);
char buffer[100]; char buffer[100];
/* Regs starting pr<foo> don't really exist */ /* Some regs dont really exist */
if (!(name[0] == 'p' && name[1] == 'r') ) { if (!(name[0] == 'p' && name[1] == 'r')
sprintf (buffer, "r %s=%x", name, read_register (regno)); && !(name[0] == 'c' && name[1] == 'y')
hms_write_cr (buffer); && !(name[0] == 't' && name[1] == 'i')
expect_prompt (); && !(name[0] == 'i' && name[1] == 'n'))
} {
sprintf (buffer, "r %s=%x", name, read_register (regno));
hms_write_cr (buffer);
expect_prompt ();
}
} }
} }
@ -1165,7 +1206,6 @@ hms_xfer_inferior_memory (memaddr, myaddr, len, write, target)
hms_store_word (addr, buffer[i]); hms_store_word (addr, buffer[i]);
if (errno) if (errno)
{ {
return 0; return 0;
} }
@ -1201,11 +1241,13 @@ hms_write_inferior_memory (memaddr, myaddr, len)
bfd_vma addr; bfd_vma addr;
int done; int done;
int todo; int todo;
char buffer[100];
done = 0; done = 0;
hms_write_cr (".");
expect_prompt ();
while (done < len) while (done < len)
{ {
char buffer[20]; char *ptr = buffer;
int thisgo; int thisgo;
int idx; int idx;
@ -1213,20 +1255,17 @@ hms_write_inferior_memory (memaddr, myaddr, len)
if (thisgo > 20) if (thisgo > 20)
thisgo = 20; thisgo = 20;
sprintf (buffer, "M.B %4x =", memaddr + done); sprintf (ptr, "M.B %4x =", memaddr + done);
hms_write (buffer, 10); ptr += 10;
for (idx = 0; idx < thisgo; idx++) for (idx = 0; idx < thisgo; idx++)
{ {
char buf[20]; sprintf (ptr, "%2x ", myaddr[idx + done]);
ptr += 3;
sprintf (buf, "%2x ", myaddr[idx + done]);
hms_write (buf, 3);
} }
hms_write_cr (""); hms_write_cr (buffer);
expect_prompt (); expect_prompt ();
done += thisgo; done += thisgo;
} }
} }
void void
@ -1262,11 +1301,6 @@ hms_read_inferior_memory (memaddr, myaddr, len)
/* Align to nearest low 16 bits */ /* Align to nearest low 16 bits */
int i; int i;
#if 0
CORE_ADDR start = memaddr & ~0xf;
CORE_ADDR end = ((memaddr + len + 16) & ~0xf) - 1;
#endif
CORE_ADDR start = memaddr; CORE_ADDR start = memaddr;
CORE_ADDR end = memaddr + len - 1; CORE_ADDR end = memaddr + len - 1;
@ -1330,32 +1364,18 @@ hms_read_inferior_memory (memaddr, myaddr, len)
} }
} }
#ifdef TARGET_IS_H8500 #ifdef GDB_TARGET_IS_H8500
expect ("ore>"); expect ("ore>");
#endif #endif
#ifdef TARGET_IS_H8300 #ifdef GDB_TARGET_IS_H8300
expect ("emory>"); expect ("emory>");
#endif #endif
hms_write_cr (" "); hms_write_cr (".");
expect_prompt (); expect_prompt ();
return len; return len;
} }
#if 0
/* This routine is run as a hook, just before the main command loop is
entered. If gdb is configured for the H8, but has not had its
target specified yet, this will loop prompting the user to do so.
*/
hms_before_main_loop ()
{
char ttyname[100];
char *p, *p2;
extern GDB_FILE *instream;
push_target (&hms_ops);
}
#endif
#define MAX_BREAKS 16 #define MAX_BREAKS 16
@ -1442,7 +1462,7 @@ hms_com (args, fromtty)
/* Clear all input so only command relative output is displayed */ /* Clear all input so only command relative output is displayed */
hms_write_cr (args); hms_write_cr (args);
hms_write ("\030", 1); /* hms_write ("\030", 1);*/
expect_prompt (); expect_prompt ();
} }
@ -1521,6 +1541,42 @@ hms_speed (s)
/***********************************************************************/ /***********************************************************************/
static void
hms_drain (args, fromtty)
char *args;
int fromtty;
{
int c;
while (1)
{
c = SERIAL_READCHAR (desc, 1);
if (c == SERIAL_TIMEOUT)
break;
if (c == SERIAL_ERROR)
break;
if (c > ' ' && c < 127)
printf ("%c", c & 0xff);
else
printf ("<%x>", c & 0xff);
}
}
static void
add_commands ()
{
add_com ("hmsdrain", class_obscure, hms_drain,
"Drain pending hms text buffers.");
}
static void
remove_commands ()
{
extern struct cmd_list_element *cmdlist;
delete_cmd ("hms-drain", &cmdlist);
}
void void
_initialize_remote_hms () _initialize_remote_hms ()
{ {