Fri Feb 4 15:53:18 1994 Steve Chamberlain (sac@cygnus.com)

* h8500-tdep.c (saved_pc_after_call): The size of the
	pc is memory model dependent. (segmented_command,
	unsegmented_command, _initialize_h8500_tdep): New commands to
	change memory model.
	* remote-7000.c (initialize_remote_e7000): Change name of snoop
	command.
	* remote-hms.c (hms_load): Remove breakpoints when loaded.
	(hms_wait): Use new status structure
	(hms_open): Push the target here. (hms_before_main_loop): Not
	here.  (supply_val, hms_fetch_register, hms_store_register):  Cope
	with H8/500 names too.
	* sh-tdep.c (show_regs, initialize_sh_tdep): New command to print
	all registers in a compact way.
This commit is contained in:
Steve Chamberlain
1994-02-05 00:22:08 +00:00
parent 9e0f78c8d7
commit edd01519b9
5 changed files with 503 additions and 129 deletions

View File

@@ -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)
compose[where++] = '\n';
compose[where++] = 0;
{
char *z;
for (z = compose; *z; z++) ;
{
/* This is ok - nothing there */
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);
}
}
}
else if (j == ENQ)
{
/* Hmm, it's trying to tell us something */
expect (":");
error ("Error writing memory");
}
else
{
printf ("Whats this %d\n", 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)
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)
{
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)
{
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.");
}