* mips-tdep.c: Replace hard-coded constants with MIPS_INSTLEN.

(common_breakpoint): Use paddr instead of %x to print 64-bit values.
	(heuristic_proc_desc): Add tests for 64-bit instructions.
	(init_extra_frame_info, mips_push_arguments): Recognize additional
	registers for EABI.
	* remote-mips.c: Extend DDB target to allow TFTP downloads.
	* config/mips/tm-mips.h (MIPS_LAST_ARG_REGNUM, MIPS_NUM_ARG_REGS):
	Define.
This commit is contained in:
Mark Alexander 1996-11-22 04:50:46 +00:00
parent 93dafa36de
commit ee45546371
3 changed files with 354 additions and 118 deletions

View File

@ -1,3 +1,14 @@
Thu Nov 21 19:13:58 1996 Mark Alexander <marka@cygnus.com>
* mips-tdep.c: Replace hard-coded constants with MIPS_INSTLEN.
(common_breakpoint): Use paddr instead of %x to print 64-bit values.
(heuristic_proc_desc): Add tests for 64-bit instructions.
(init_extra_frame_info, mips_push_arguments): Recognize additional
registers for EABI.
* remote-mips.c: Extend DDB target to allow TFTP downloads.
* config/mips/tm-mips.h (MIPS_LAST_ARG_REGNUM, MIPS_NUM_ARG_REGS):
Define.
Wed Nov 20 19:09:16 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
* infcmd.c (do_registers_info): Call val_print with the

View File

@ -163,6 +163,13 @@ extern int in_sigtramp PARAMS ((CORE_ADDR, char *));
#define ZERO_REGNUM 0 /* read-only register, always 0 */
#define V0_REGNUM 2 /* Function integer return value */
#define A0_REGNUM 4 /* Loc of first arg during a subr call */
#if MIPS_EABI
#define MIPS_LAST_ARG_REGNUM 11 /* EABI uses R4 through R11 for args */
#define MIPS_NUM_ARG_REGS 8
#else
#define MIPS_LAST_ARG_REGNUM 7 /* old ABI uses R4 through R7 for args */
#define MIPS_NUM_ARG_REGS 4
#endif
#define SP_REGNUM 29 /* Contains address of top of stack */
#define RA_REGNUM 31 /* Contains return address value */
#define PS_REGNUM 32 /* Contains processor status */

View File

@ -29,8 +29,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "serial.h"
#include "target.h"
#include "remote-utils.h"
#include "gdb_string.h"
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef ANSI_PROTOTYPES
#include <stdarg.h>
#else
@ -118,7 +121,13 @@ static void pmon_make_fastrec PARAMS ((char **outbuf, unsigned char *inbuf,
int *inptr, int inamount, int *recsize,
unsigned int *csum, unsigned int *zerofill));
static int pmon_check_ack PARAMS ((void));
static int pmon_check_ack PARAMS ((char *mesg));
static void pmon_start_download PARAMS ((void));
static void pmon_end_download PARAMS ((int final, int bintotal));
static void pmon_download PARAMS ((char *buffer, int length));
static void pmon_load_fast PARAMS ((char *file));
@ -239,7 +248,7 @@ extern struct target_ops ddb_ops;
(((hdr)[HDR_INDX_TYPE_LEN] & TYPE_LEN_DA_BIT) == TYPE_LEN_DATA)
#define HDR_GET_LEN(hdr) \
((((hdr)[HDR_INDX_TYPE_LEN] & 0x1f) << 6) + (((hdr)[HDR_INDX_LEN1] & 0x3f)))
#define HDR_GET_SEQ(hdr) ((hdr)[HDR_INDX_SEQ] & 0x3f)
#define HDR_GET_SEQ(hdr) ((unsigned int)(hdr)[HDR_INDX_SEQ] & 0x3f)
/* The maximum data length. */
#define DATA_MAXLEN 1023
@ -271,6 +280,10 @@ extern struct target_ops ddb_ops;
/* The sequence number modulos. */
#define SEQ_MODULOS (64)
/* PMON commands to load from the serial port or UDP socket. */
#define LOAD_CMD "load -b -s tty0\r"
#define LOAD_CMD_UDP "load -b -s udp\r"
enum mips_monitor_type {
/* IDT/SIM monitor being used: */
MON_IDT,
@ -329,6 +342,17 @@ static int mips_need_reply = 0;
/* Handle used to access serial I/O stream. */
static serial_t mips_desc;
/* UDP handle used to download files to target. */
static serial_t udp_desc;
static int udp_in_use;
/* TFTP filename used to download files to DDB board, in the form
host:filename. */
static char *tftp_name; /* host:filename */
static char *tftp_localname; /* filename portion of above */
static int tftp_in_use;
static FILE *tftp_file;
/* Counts the number of times the user tried to interrupt the target (usually
via ^C. */
static int interrupt_count;
@ -341,11 +365,27 @@ static monitor_supports_breakpoints = 0;
/* Data cache header. */
#if 0 /* not used (yet?) */
static DCACHE *mips_dcache;
#endif
/* Non-zero means that we've just hit a read or write watchpoint */
static int hit_watchpoint;
static void
close_ports()
{
mips_is_open = 0;
SERIAL_CLOSE (mips_desc);
if (udp_in_use)
{
SERIAL_CLOSE (udp_desc);
udp_in_use = 0;
}
tftp_in_use = 0;
}
/* Handle low-level error that we can't recover from. Note that just
error()ing out from target_wait or some such low-level place will cause
all hell to break loose--the rest of GDB will tend to get left in an
@ -382,8 +422,7 @@ mips_error (va_alist)
/* Clean up in such a way that mips_close won't try to talk to the
board (it almost surely won't work since we weren't able to talk to
it). */
mips_is_open = 0;
SERIAL_CLOSE (mips_desc);
close_ports ();
printf_unfiltered ("Ending remote MIPS debugging.\n");
target_mourn_inferior ();
@ -391,15 +430,58 @@ mips_error (va_alist)
return_to_top_level (RETURN_ERROR);
}
/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if
timed out. */
/* putc_readable - print a character, displaying non-printable chars in
^x notation or in hex. */
int
mips_expect (string)
static void
putc_readable (ch)
int ch;
{
if (ch == '\n')
putchar_unfiltered ('\n');
else if (ch == '\r')
printf_unfiltered ("\\r");
else if (ch < 0x20) /* ASCII control character */
printf_unfiltered ("^%c", ch + '@');
else if (ch >= 0x7f) /* non-ASCII characters (rubout or greater) */
printf_unfiltered ("[%02x]", ch & 0xff);
else
putchar_unfiltered (ch);
}
/* puts_readable - print a string, displaying non-printable chars in
^x notation or in hex. */
static void
puts_readable (string)
char *string;
{
int c;
while ((c = *string++) != '\0')
putc_readable (c);
}
/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if
timed out. TIMEOUT specifies timeout value in seconds.
*/
int
mips_expect_timeout (string, timeout)
char *string;
int timeout;
{
char *p = string;
if (remote_debug)
{
printf_unfiltered ("Expected \"");
puts_readable (string);
printf_unfiltered ("\", got \"");
}
immediate_quit = 1;
while (1)
{
@ -408,16 +490,25 @@ mips_expect (string)
/* Must use SERIAL_READCHAR here cuz mips_readchar would get confused if we
were waiting for the mips_monitor_prompt... */
c = SERIAL_READCHAR (mips_desc, 2);
c = SERIAL_READCHAR (mips_desc, timeout);
if (c == SERIAL_TIMEOUT)
return 0;
{
if (remote_debug)
printf_unfiltered ("\": FAIL\n");
return 0;
}
if (remote_debug)
putc_readable (c);
if (c == *p++)
{
if (*p == '\0')
{
immediate_quit = 0;
if (remote_debug)
printf_unfiltered ("\": OK\n");
return 1;
}
}
@ -430,6 +521,18 @@ mips_expect (string)
}
}
/* Wait until STRING shows up in mips_desc. Returns 1 if successful, else 0 if
timed out. The timeout value is hard-coded to 2 seconds. Use
mips_expect_timeout if a different timeout value is needed.
*/
int
mips_expect (string)
char *string;
{
return mips_expect_timeout (string, 2);
}
/* Read the required number of characters into the given buffer (which
is assumed to be large enough). The only failure is a timeout. */
int
@ -481,7 +584,7 @@ mips_readchar (timeout)
/* NASTY, since we assume that the prompt does not change after the
first mips_readchar call: */
if (mips_monitor_prompt_len = -1)
if (mips_monitor_prompt_len == -1)
mips_monitor_prompt_len = strlen(mips_monitor_prompt);
#ifdef MAINTENANCE_CMDS
@ -584,19 +687,7 @@ mips_receive_header (hdr, pgarbage, ch, timeout)
we can't deal with a QUIT out of target_wait. */
if (! mips_initializing || remote_debug > 0)
{
/* Note that the host's idea of newline may not
correspond to the target's idea, so recognize
newline by its actual ASCII code, but write it
out using the \n notation. */
if (ch < 0x20 && ch != '\012')
{
putchar_unfiltered ('^');
putchar_unfiltered (ch + 0x40);
}
else if (ch == '\012')
putchar_unfiltered ('\n');
else
putchar_unfiltered (ch);
putc_readable (ch);
gdb_flush (gdb_stdout);
}
@ -692,7 +783,7 @@ mips_send_packet (s, get_ack)
const char *s;
int get_ack;
{
unsigned int len;
/* unsigned */ int len;
unsigned char *packet;
register int cksum;
int try;
@ -749,7 +840,7 @@ mips_send_packet (s, get_ack)
unsigned char hdr[HDR_LENGTH + 1];
unsigned char trlr[TRLR_LENGTH + 1];
int err;
int seq;
unsigned int seq;
/* Get the packet header. If we time out, resend the data
packet. */
@ -1145,7 +1236,7 @@ mips_send_command (cmd, prompt)
{
SERIAL_WRITE (mips_desc, cmd, strlen(cmd));
mips_expect (cmd);
mips_expect ("\012");
mips_expect ("\n");
if (prompt)
mips_expect (mips_monitor_prompt);
}
@ -1159,18 +1250,18 @@ mips_enter_debug ()
mips_receive_seq = 0;
if (mips_monitor == MON_PMON || mips_monitor == MON_DDB)
mips_send_command ("debug\015", 0);
mips_send_command ("debug\r", 0);
else /* assume IDT monitor by default */
mips_send_command ("db tty0\015", 0);
mips_send_command ("db tty0\r", 0);
SERIAL_WRITE (mips_desc, "\015", sizeof "\015" - 1);
SERIAL_WRITE (mips_desc, "\r", sizeof "\r" - 1);
/* We don't need to absorb any spurious characters here, since the
mips_receive_header will eat up a reasonable number of characters
whilst looking for the SYN, however this avoids the "garbage"
being displayed to the user. */
if (mips_monitor == MON_PMON || mips_monitor == MON_DDB)
mips_expect ("\015");
mips_expect ("\r");
{
char buff[DATA_MAXLEN + 1];
@ -1204,11 +1295,11 @@ mips_exit_debug ()
if (mips_monitor == MON_DDB)
{
if (!mips_expect ("\012"))
if (!mips_expect ("\n"))
return -1;
}
else
if (!mips_expect ("\015\012"))
if (!mips_expect ("\r\n"))
return -1;
if (!mips_expect (mips_monitor_prompt))
@ -1255,7 +1346,7 @@ mips_initialize ()
{
case 0: /* First, try sending a CR */
SERIAL_FLUSH_INPUT (mips_desc);
SERIAL_WRITE (mips_desc, "\015", 1);
SERIAL_WRITE (mips_desc, "\r", 1);
break;
case 1: /* First, try sending a break */
SERIAL_SEND_BREAK (mips_desc);
@ -1276,7 +1367,7 @@ mips_initialize ()
we flush the output buffer before inserting a
termination sequence. */
SERIAL_FLUSH_OUTPUT (mips_desc);
sprintf (tbuff, "\015/E/E\015");
sprintf (tbuff, "\r/E/E\r");
SERIAL_WRITE (mips_desc, tbuff, 6);
}
else
@ -1317,11 +1408,11 @@ mips_initialize ()
if (mips_monitor == MON_PMON || mips_monitor == MON_DDB)
{
/* Ensure the correct target state: */
mips_send_command ("set regsize 64\015", -1);
mips_send_command ("set hostport tty0\015", -1);
mips_send_command ("set brkcmd \"\"\015", -1);
mips_send_command ("set regsize 64\r", -1);
mips_send_command ("set hostport tty0\r", -1);
mips_send_command ("set brkcmd \"\"\r", -1);
/* Delete all the current breakpoints: */
mips_send_command ("db *\015", -1);
mips_send_command ("db *\r", -1);
/* NOTE: PMON does not have breakpoint support through the
"debug" mode, only at the monitor command-line. */
}
@ -1353,39 +1444,97 @@ common_open (ops, name, from_tty)
int from_tty;
{
char *ptype;
char *serial_port_name;
char *remote_name = 0;
char *local_name = 0;
char **argv;
if (name == 0)
error (
"To open a MIPS remote debugging connection, you need to specify what serial\n\
device is attached to the target board (e.g., /dev/ttya).");
device is attached to the target board (e.g., /dev/ttya).\n"
"If you want to use TFTP to download to the board, specify the name of a\n"
"temporary file to be used by GDB for downloads as the second argument.\n"
"This filename must be in the form host:filename, where host is the name\n"
"of the host running the TFTP server, and the file must be readable by the\n"
"world. If the local name of the temporary file differs from the name as\n",
"seen from the board via TFTP, specify that name as the third parameter\n");
/* Parse the serial port name, the optional TFTP name, and the
optional local TFTP name. */
if ((argv = buildargv (name)) == NULL)
nomem(0);
make_cleanup (freeargv, (char *) argv);
serial_port_name = strsave (argv[0]);
if (argv[1]) /* remote TFTP name specified? */
{
remote_name = argv[1];
if (argv[2]) /* local TFTP filename specified? */
local_name = argv[2];
}
target_preopen (from_tty);
if (mips_is_open)
unpush_target (current_ops);
mips_desc = SERIAL_OPEN (name);
/* Open and initialize the serial port. */
mips_desc = SERIAL_OPEN (serial_port_name);
if (mips_desc == (serial_t) NULL)
perror_with_name (name);
perror_with_name (serial_port_name);
if (baud_rate != -1)
{
if (SERIAL_SETBAUDRATE (mips_desc, baud_rate))
{
SERIAL_CLOSE (mips_desc);
perror_with_name (name);
perror_with_name (serial_port_name);
}
}
SERIAL_RAW (mips_desc);
/* Open and initialize the optional download port. If it is in the form
hostname#portnumber, it's a UDP socket. If it is in the form
hostname:filename, assume it's the TFTP filename that must be
passed to the DDB board to tell it where to get the load file. */
if (remote_name)
{
if (strchr (remote_name, '#'))
{
udp_desc = SERIAL_OPEN (remote_name);
if (!udp_desc)
perror_with_name ("Unable to open UDP port");
udp_in_use = 1;
}
else
{
/* Save the remote and local names of the TFTP temp file. If
the user didn't specify a local name, assume it's the same
as the part of the remote name after the "host:". */
if (tftp_name)
free (tftp_name);
if (tftp_localname)
free (tftp_localname);
if (local_name == NULL)
if ((local_name = strchr (remote_name, ':')) != NULL)
local_name++; /* skip over the colon */
if (local_name == NULL)
local_name = remote_name; /* local name same as remote name */
tftp_name = strsave (remote_name);
tftp_localname = strsave (local_name);
tftp_in_use = 1;
}
}
current_ops = ops;
mips_is_open = 1;
mips_initialize ();
if (from_tty)
printf_unfiltered ("Remote MIPS debugging using %s\n", name);
printf_unfiltered ("Remote MIPS debugging using %s\n", serial_port_name);
/* Switch to using remote target now. */
push_target (ops);
@ -1408,6 +1557,7 @@ device is attached to the target board (e.g., /dev/ttya).");
set_current_frame (create_new_frame (read_fp (), stop_pc));
select_frame (get_current_frame (), 0);
print_stack_frame (selected_frame, -1, 1);
free (serial_port_name);
}
static void
@ -1451,14 +1601,10 @@ mips_close (quitting)
{
if (mips_is_open)
{
int err;
mips_is_open = 0;
/* Get the board out of remote debugging mode. */
(void) mips_exit_debug ();
SERIAL_CLOSE (mips_desc);
close_ports ();
}
}
@ -1732,7 +1878,7 @@ static void
mips_fetch_registers (regno)
int regno;
{
ULONGEST val;
unsigned LONGEST val;
int err;
if (regno == -1)
@ -1977,8 +2123,7 @@ Give up (and stop debugging it)? "))
board (it almost surely won't work since we weren't able to talk to
it). */
mips_wait_flag = 0;
mips_is_open = 0;
SERIAL_CLOSE (mips_desc);
close_ports();
printf_unfiltered ("Ending remote MIPS debugging.\n");
target_mourn_inferior ();
@ -2079,8 +2224,6 @@ mips_insert_breakpoint (addr, contents_cache)
CORE_ADDR addr;
char *contents_cache;
{
int status;
if (monitor_supports_breakpoints)
return common_breakpoint ('B', addr, 0x3, "f");
@ -2126,7 +2269,7 @@ pmon_insert_breakpoint (addr, contents_cache)
if (mips_exit_debug ())
mips_error ("Failed to exit debug mode");
sprintf (tbuff, "b %08x\015", addr);
sprintf (tbuff, "b %08x\r", addr);
mips_send_command (tbuff, 0);
mips_expect ("Bpt ");
@ -2170,7 +2313,7 @@ pmon_insert_breakpoint (addr, contents_cache)
mips_pmon_bp_info[bpnum] = bpaddr;
mips_expect ("\015\012");
mips_expect ("\r\n");
mips_expect (mips_monitor_prompt);
mips_enter_debug ();
@ -2204,7 +2347,7 @@ pmon_remove_breakpoint (addr, contents_cache)
if (mips_exit_debug ())
mips_error ("Failed to exit debug mode");
sprintf (tbuff, "db %02d\015", bpnum);
sprintf (tbuff, "db %02d\r", bpnum);
mips_send_command (tbuff, -1);
/* NOTE: If the breakpoint does not exist then a "Bpt <dd> not
@ -2328,9 +2471,9 @@ common_breakpoint (cmd, addr, mask, flags)
int nfields;
if (flags)
sprintf (buf, "0x0 %c 0x%x 0x%x %s", cmd, addr, mask, flags);
sprintf (buf, "0x0 %c 0x%s 0x%s %s", cmd, paddr (addr), paddr (mask), flags);
else
sprintf (buf, "0x0 %c 0x%x", cmd, addr);
sprintf (buf, "0x0 %c 0x%s", cmd, paddr (addr));
mips_send_packet (buf, 1);
@ -2397,8 +2540,8 @@ mips_load_srec (args)
bfd *abfd;
asection *s;
char *buffer, srec[1024];
int i;
int srec_frame = 200;
unsigned int i;
unsigned int srec_frame = 200;
int reclen;
static int hashmark = 1;
@ -2418,14 +2561,13 @@ mips_load_srec (args)
}
/* This actually causes a download in the IDT binary format: */
#define LOAD_CMD "load -b -s tty0\015"
mips_send_command (LOAD_CMD, 0);
for (s = abfd->sections; s; s = s->next)
{
if (s->flags & SEC_LOAD)
{
int numbytes;
unsigned int numbytes;
/* FIXME! vma too small?? */
printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma,
@ -2646,7 +2788,7 @@ pmon_checkset (recsize, buff, value)
sprintf (*buff, "/C");
count = pmon_makeb64 (*value, (*buff + 2), 12, NULL);
*buff += (count + 2);
sprintf (*buff, "\015");
sprintf (*buff, "\n");
*buff += 2; /* include zero terminator */
/* Forcing a checksum validation clears the sum: */
*value = 0;
@ -2722,18 +2864,112 @@ pmon_make_fastrec (outbuf, inbuf, inptr, inamount, recsize, csum, zerofill)
return;
}
#if defined(DOETXACK)
static int
pmon_check_ack()
pmon_check_ack(mesg)
char *mesg;
{
int c = SERIAL_READCHAR (mips_desc, 2);
if ((c == SERIAL_TIMEOUT) || (c != 0x06)) {
fprintf_unfiltered (gdb_stderr, "Failed to receive valid ACK\n");
return(-1); /* terminate the download */
}
#if defined(DOETXACK)
int c;
if (!tftp_in_use)
{
c = SERIAL_READCHAR (udp_in_use ? udp_desc : mips_desc, 2);
if ((c == SERIAL_TIMEOUT) || (c != 0x06))
{
fprintf_unfiltered (gdb_stderr,
"Failed to receive valid ACK for %s\n", mesg);
return(-1); /* terminate the download */
}
}
#endif /* DOETXACK */
return(0);
}
#endif /* DOETXACK */
/* pmon_download - Send a sequence of characters to the PMON download port,
which is either a serial port or a UDP socket. */
static void
pmon_start_download ()
{
if (tftp_in_use)
{
/* Create the temporary download file. */
if ((tftp_file = fopen (tftp_localname, "w")) == NULL)
perror_with_name (tftp_localname);
}
else
{
mips_send_command (udp_in_use ? LOAD_CMD_UDP : LOAD_CMD, 0);
mips_expect ("Downloading from ");
mips_expect (udp_in_use ? "udp" : "tty0");
mips_expect (", ^C to abort\r\n");
}
}
static void
pmon_end_download (final, bintotal)
int final;
int bintotal;
{
char hexnumber[9]; /* includes '\0' space */
if (tftp_in_use)
{
static char *load_cmd_prefix = "load -b -s ";
char *cmd;
struct stat stbuf;
/* Close off the temporary file containing the load data. */
fclose (tftp_file);
tftp_file = NULL;
/* Make the temporary file readable by the world. */
if (stat (tftp_localname, &stbuf) == 0)
chmod (tftp_localname, stbuf.st_mode | S_IROTH);
/* Must reinitialize the board to prevent PMON from crashing. */
mips_send_command ("initEther\r", -1);
/* Send the load command. */
cmd = xmalloc (strlen (load_cmd_prefix) + strlen (tftp_name) + 2);
strcpy (cmd, load_cmd_prefix);
strcat (cmd, tftp_name);
strcat (cmd, "\r");
mips_send_command (cmd, 0);
free (cmd);
mips_expect ("Downloading from ");
mips_expect (tftp_name);
mips_expect (", ^C to abort\r\n");
}
/* Wait for the stuff that PMON prints after the load has completed.
The timeout value for use in the tftp case (15 seconds) was picked
arbitrarily but might be too small for really large downloads. FIXME. */
mips_expect_timeout ("Entry Address = ", tftp_in_use ? 15 : 2);
sprintf (hexnumber,"%x",final);
mips_expect (hexnumber);
mips_expect ("\r\n");
pmon_check_ack ("termination");
mips_expect ("\r\ntotal = 0x");
sprintf (hexnumber,"%x",bintotal);
mips_expect (hexnumber);
if (!mips_expect (" bytes\r\n"))
fprintf_unfiltered (gdb_stderr, "Load did not complete successfully.\n");
if (tftp_in_use)
remove (tftp_localname); /* Remove temporary file */
}
static void
pmon_download (buffer, length)
char *buffer;
int length;
{
if (tftp_in_use)
fwrite (buffer, 1, length, tftp_file);
else
SERIAL_WRITE (udp_in_use ? udp_desc : mips_desc, buffer, length);
}
static void
pmon_load_fast (file)
@ -2745,9 +2981,9 @@ pmon_load_fast (file)
char *buffer;
int reclen;
unsigned int csum = 0;
static int hashmark = 1;
int hashmark = !tftp_in_use;
int bintotal = 0;
int final;
int final = 0;
int finished = 0;
buffer = (char *)xmalloc(MAXRECSIZE + 1);
@ -2767,23 +3003,19 @@ pmon_load_fast (file)
}
/* Setup the required download state: */
mips_send_command ("set dlproto etxack\015", -1);
mips_send_command ("set dlecho off\015", -1);
mips_send_command ("set dlproto etxack\r", -1);
mips_send_command ("set dlecho off\r", -1);
/* NOTE: We get a "cannot set variable" message if the variable is
already defined to have the argument we give. The code doesn't
care, since it just scans to the next prompt anyway. */
/* Start the download: */
mips_send_command (LOAD_CMD, 0);
mips_expect ("Downloading from tty0, ^C to abort\015\012");
pmon_start_download();
/* Zero the checksum */
sprintf(buffer,"/Kxx\015");
sprintf(buffer,"/Kxx\n");
reclen = strlen(buffer);
SERIAL_WRITE (mips_desc, buffer, reclen);
#if defined(DOETXACK)
finished = pmon_check_ack();
#endif /* DOETXACK */
pmon_download (buffer, reclen);
finished = pmon_check_ack("/Kxx");
for (s = abfd->sections; s && !finished; s = s->next)
if (s->flags & SEC_LOAD) /* only deal with loadable sections */
@ -2798,20 +3030,18 @@ pmon_load_fast (file)
/* Output the starting address */
sprintf(buffer,"/A");
reclen = pmon_makeb64(s->vma,&buffer[2],36,&csum);
buffer[2 + reclen] = '\015';
buffer[2 + reclen] = '\n';
buffer[3 + reclen] = '\0';
reclen += 3; /* for the initial escape code and carriage return */
SERIAL_WRITE (mips_desc, buffer, reclen);
#if defined(DOETXACK)
finished = pmon_check_ack();
#endif /* DOETXACK */
pmon_download (buffer, reclen);
finished = pmon_check_ack("/A");
if (!finished)
{
int binamount;
unsigned int binamount;
unsigned int zerofill = 0;
char *bp = buffer;
int i;
unsigned int i;
reclen = 0;
@ -2828,14 +3058,12 @@ pmon_load_fast (file)
pmon_make_fastrec (&bp, binbuf, &binptr, binamount, &reclen, &csum, &zerofill);
if (reclen >= (MAXRECSIZE - CHECKSIZE)) {
reclen = pmon_checkset (reclen, &bp, &csum);
SERIAL_WRITE (mips_desc, buffer, reclen);
#if defined(DOETXACK)
finished = pmon_check_ack();
pmon_download (buffer, reclen);
finished = pmon_check_ack("data record");
if (finished) {
zerofill = 0; /* do not transmit pending zerofills */
break;
}
#endif /* DOETXACK */
if (hashmark) {
putchar_unfiltered ('#');
@ -2857,38 +3085,24 @@ pmon_load_fast (file)
reclen = pmon_checkset (reclen, &bp, &csum);
/* Currently pmon_checkset outputs the line terminator by
default, so we write out the buffer so far: */
SERIAL_WRITE (mips_desc, buffer, reclen);
#if defined(DOETXACK)
finished = pmon_check_ack();
#endif /* DOETXACK */
pmon_download (buffer, reclen);
finished = pmon_check_ack("record remnant");
}
}
if (hashmark)
putchar_unfiltered ('\n');
putchar_unfiltered ('\n');
}
/* Terminate the transfer. We know that we have an empty output
buffer at this point. */
sprintf (buffer, "/E/E\015"); /* include dummy padding characters */
sprintf (buffer, "/E/E\n"); /* include dummy padding characters */
reclen = strlen (buffer);
SERIAL_WRITE (mips_desc, buffer, reclen);
pmon_download (buffer, reclen);
if (finished) { /* Ignore the termination message: */
SERIAL_FLUSH_INPUT (mips_desc);
SERIAL_FLUSH_INPUT (udp_in_use ? udp_desc : mips_desc);
} else { /* Deal with termination message: */
char hexnumber[9]; /* includes '\0' space */
mips_expect ("Entry Address = ");
sprintf(hexnumber,"%x",final);
mips_expect (hexnumber);
#if defined(DOETXACK)
mips_expect ("\015\012\006\015\012total = 0x");
#else /* normal termination */
mips_expect ("\015\012\015\012total = 0x");
#endif /* !DOETXACK */
sprintf(hexnumber,"%x",bintotal);
mips_expect (hexnumber);
mips_expect (" bytes\015\012");
pmon_end_download (final, bintotal);
}
return;
@ -3040,8 +3254,12 @@ struct target_ops ddb_ops =
"Remote MIPS debugging over serial line", /* to_longname */
"\
Debug a board using the PMON MIPS remote debugging protocol over a serial\n\
line. The argument is the device it is connected to or, if it contains a\n\
colon, HOST:PORT to access a board over a network", /* to_doc */
line. The first argument is the device it is connected to or, if it contains\n\
a colon, HOST:PORT to access a board over a network. The optional second\n\
parameter is the temporary file in the form HOST:FILENAME to be used for\n\
TFTP downloads to the board. The optional third parameter is the local\n\
of the TFTP temporary file, if it differs from the filename seen by the board",
/* to_doc */
ddb_open, /* to_open */
mips_close, /* to_close */
NULL, /* to_attach */