* monitor.c (set_loadtype_command): Fixed so it doesn't core dump.

* monitor.c (monitor_load): check the load type and load the file
	accordingly. Default to gr_load_image().
	* monitor.c (monitor_load_ascii_srec): Load an ascii file in
	srecord format by downloading to the monitor.
	* w89k-rom.c, op50n-rom.c: set supported load types.
This commit is contained in:
Rob Savoye 1994-10-18 00:55:51 +00:00
parent b7881f82ee
commit 21ed3dcdbe
3 changed files with 288 additions and 47 deletions

View File

@ -52,6 +52,9 @@ struct monitor_ops *current_monitor;
extern struct cmd_list_element *setlist;
extern struct cmd_list_element *unsetlist;
struct cmd_list_element *showlist;
extern char *version;
extern char *host_name;
extern char *target_name;
static int hashmark; /* flag set by "set hash" */
@ -72,6 +75,8 @@ static serial_t monitor_desc = NULL;
char *loadtype;
static char *loadtype_str;
static void set_loadtype_command();
static void monitor_load_srec();
static int monitor_write_srec();
/*
* set_loadtype_command -- set the type for downloading. Check to make
@ -83,24 +88,27 @@ set_loadtype_command (ignore, from_tty, c)
int from_tty;
struct cmd_list_element *c;
{
#if 0
char *tmp;
char *type;
if (strcmp (LOADTYPES, "")) {
if (STREQ (LOADTYPES, "")) {
error ("No loadtype set");
return;
}
type = strtok(LOADTYPES, ",");
tmp = savestring (LOADTYPES, strlen(LOADTYPES));
type = strtok(tmp, ",");
if (STREQ (type, (*(char **) c->var))) {
loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
return;
}
while (type = strtok (NULL, ",") != (char *)NULL)
while ((type = strtok (NULL, ",")) != (char *)NULL) {
if (STREQ (type, (*(char **) c->var)))
loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
#endif
loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
return;
}
free (tmp);
error ("Loadtype \"%s\" does not exist.", (*(char **) c->var));
}
/*
@ -473,6 +481,9 @@ monitor_open(args, name, from_tty)
log_file = fopen (LOG_FILE, "w");
if (log_file == NULL)
perror_with_name (LOG_FILE);
fprintf_filtered (log_file, "GDB %s (%s", version, host_name);
fprintf_filtered (log_file, " --target %s)\n", target_name);
fprintf_filtered (log_file, "Remote target %s connected to %s\n\n", TARGET_NAME, dev_name);
#endif
/* wake up the monitor and see if it's alive */
@ -949,60 +960,96 @@ monitor_remove_breakpoint (addr, shadow)
return 1;
}
/* Load a file. This is usually an srecord, which is ascii. No
protocol, just sent line by line. */
#define DOWNLOAD_LINE_SIZE 100
/* monitor_load -- load a file. This file determines which of the
* supported formats to use. The current types are:
* FIXME: not all types supported yet.
* default - reads any file using bfd and writes it to memory.
* srec - reads binary file using bfd and writes it as an
* ascii srecord.
* xmodem-bin - reads a binary file using bfd, and downloads it
* using xmodem protocol.
* xmodem-srec - reads a binary file using bfd, and after converting
* it downloads it as an srecord using xmodem protocol.
* ascii-srec - reads a ascii srecord file and downloads it
* without a change.
* ascii-xmodem - reads a ascii file and downloads using xmodem
* protocol.
*/
void
monitor_load (arg)
char *arg;
monitor_load (file, fromtty)
char *file;
int fromtty;
{
FILE *download;
int i, bytes_read;
debuglogs (1, "Loading %s to monitor", file);
if (STREQ (loadtype_str, "default")) { /* default, load a binary */
gr_load_image (file, fromtty); /* by writing it into memory */
}
if (STREQ (loadtype_str, "srec")) { /* load an srecord by converting */
monitor_load_srec(file, fromtty); /* if from a binary */
}
if (STREQ (loadtype_str, "ascii-srec")) { /* load an srecord file */
monitor_load_ascii_srec(file, fromtty); /* if from a binary */
}
if (STREQ (loadtype_str, "xmodem-srec")) { /* load an srecord using the */
error ("This protocol is not implemented yet."); /* xmodem protocol */
}
}
/*
* monitor_load_ascii_srec -- download an ASCII srecord file.
*/
#define DOWNLOAD_LINE_SIZE 100
int
monitor_load_ascii_srec (file, fromtty)
char *file;
int fromtty;
{
FILE *download;
char buf[DOWNLOAD_LINE_SIZE];
int i, bytes_read;
if (sr_get_debug())
printf ("Loading %s to monitor\n", arg);
debuglogs (1, "Loading an ASCII srecord file, %s.", file);
download = fopen (arg, "r");
if (download == NULL)
{
error (sprintf (buf, "%s Does not exist", arg));
download = fopen (file, "r");
if (download == NULL) {
error ("%s Does not exist", file);
return;
}
printf_monitor (LOAD_CMD);
/* expect ("Waiting for S-records from host... ", 1); */
while (!feof (download))
{
bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
if (hashmark)
{
putchar ('.');
fflush (stdout);
}
if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
break;
}
i = 0;
while (i++ <=200000) {} ; /* Ugly HACK, probably needs flow control */
if (bytes_read < DOWNLOAD_LINE_SIZE)
{
if (!feof (download))
error ("Only read %d bytes\n", bytes_read);
break;
}
while (!feof (download)) {
bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
if (hashmark) {
putchar ('.');
fflush (stdout);
}
if (hashmark)
{
putchar ('\n');
if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
break;
}
i = 0;
while (i++ <=200) {} ; /* Ugly HACK, probably needs flow control */
if (bytes_read < DOWNLOAD_LINE_SIZE) {
if (!feof (download))
error ("Only read %d bytes\n", bytes_read);
break;
}
}
if (hashmark) {
putchar ('\n');
}
if (!feof (download))
error ("Never got EOF while downloading");
expect_prompt(1);
fclose (download);
}
@ -1035,6 +1082,200 @@ monitor_command (args, fromtty)
expect_prompt(0);
}
/*
* monitor_load_srec -- download a binary file by converting it to srecords.
*/
static void
monitor_load_srec (args, fromtty)
char *args;
int fromtty;
{
bfd *abfd;
asection *s;
char buffer[1024];
int srec_frame = SREC_SIZE;
abfd = bfd_openr (args, 0);
if (!abfd) {
printf_filtered ("Unable to open file %s\n", args);
return;
}
if (bfd_check_format (abfd, bfd_object) == 0) {
printf_filtered ("File is not an object file\n");
return;
}
s = abfd->sections;
while (s != (asection *) NULL) {
srec_frame = SREC_SIZE;
if (s->flags & SEC_LOAD) {
int i;
char *buffer = xmalloc (srec_frame);
printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma, s->vma + s
->_raw_size);
fflush (stdout);
for (i = 0; i < s->_raw_size; i += srec_frame) {
if (srec_frame > s->_raw_size - i)
srec_frame = s->_raw_size - i;
bfd_get_section_contents (abfd, s, buffer, i, srec_frame);
monitor_write_srec (s->vma + i, buffer, srec_frame);
printf_filtered ("*");
fflush (stdout);
}
printf_filtered ("\n");
free (buffer);
}
s = s->next;
}
sprintf (buffer, "rs ip %lx", (unsigned long) abfd->start_address);
printf_monitor (buffer);
expect_prompt ();
}
static int
monitor_write_srec (memaddr, myaddr, len)
CORE_ADDR memaddr;
unsigned char *myaddr;
int len;
{
int done;
int checksum;
int x;
int retries;
int srec_bytes = 40;
int srec_max_retries = 3;
int srec_echo_pace = 0;
int srec_sleep = 0;
int srec_noise = 0;
char *buffer = alloca ((srec_bytes + 8) << 1);
retries = 0;
while (1) { /* FIXME !!! */
done = 0;
if (retries > srec_max_retries)
return(-1);
if (retries > 0) {
if (sr_get_debug() > 0)
printf("\n<retrying...>\n");
/* This gr_expect_prompt call is extremely important. Without
it, we will tend to resend our packet so fast that it
will arrive before the bug monitor is ready to receive
it. This would lead to a very ugly resend loop. */
gr_expect_prompt();
}
/* FIXME: this is just start_load pasted in... */
{ char *command;
command = (srec_echo_pace ? "lo 0 ;x" : "lo 0");
sr_write_cr (command);
sr_expect (command);
sr_expect ("\r\n");
#if 0
bug_srec_write_cr ("S0030000FC");
#endif
}
/* end of hack */
while (done < len) {
int thisgo;
int idx;
char *buf = buffer;
CORE_ADDR address;
checksum = 0;
thisgo = len - done;
if (thisgo > srec_bytes)
thisgo = srec_bytes;
address = memaddr + done;
sprintf (buf, "S3%02X%08X", thisgo + 4 + 1, address);
buf += 12;
checksum += (thisgo + 4 + 1
+ (address & 0xff)
+ ((address >> 8) & 0xff)
+ ((address >> 16) & 0xff)
+ ((address >> 24) & 0xff));
for (idx = 0; idx < thisgo; idx++) {
sprintf (buf, "%02X", myaddr[idx + done]);
checksum += myaddr[idx + done];
buf += 2;
}
if (srec_noise > 0) {
/* FIXME-NOW: insert a deliberate error every now and then.
This is intended for testing/debugging the error handling
stuff. */
static int counter = 0;
if (++counter > srec_noise) {
counter = 0;
++checksum;
}
}
sprintf(buf, "%02X", ~checksum & 0xff);
#if 0
bug_srec_write_cr (buffer);
#endif
if (srec_sleep != 0)
sleep(srec_sleep);
/* This pollchar is probably redundant to the gr_multi_scan
below. Trouble is, we can't be sure when or where an
error message will appear. Apparently, when running at
full speed from a typical sun4, error messages tend to
appear to arrive only *after* the s7 record. */
if ((x = sr_pollchar()) != 0) {
if (sr_get_debug() > 0)
printf("\n<retrying...>\n");
++retries;
/* flush any remaining input and verify that we are back
at the prompt level. */
gr_expect_prompt();
/* start all over again. */
/* FIXME: this is just start_load pasted in... */
{ char *command;
command = (srec_echo_pace ? "lo 0 ;x" : "lo 0");
sr_write_cr (command);
sr_expect (command);
sr_expect ("\r\n");
#if 0
bug_srec_write_cr ("S0030000FC");
#endif
}
/* end of hack */
done = 0;
continue;
}
done += thisgo;
}
#if 0
bug_srec_write_cr("S7060000000000F9");
#endif
++retries;
/* Having finished the load, we need to figure out whether we
had any errors. */
}
return(0);
}
/*
* _initialize_remote_monitors -- setup a few addtitional commands that
* are usually only used by monitors.
@ -1049,7 +1290,7 @@ _initialize_remote_monitors ()
"Set the type of the remote load protocol.\n", &setlist);
c->function.sfunc = set_loadtype_command;
add_show_from_set (c, &showlist);
loadtype_str = savestring ("generic", 8);
loadtype_str = savestring ("default", 8);
add_show_from_set (add_set_cmd ("hash", no_class, var_boolean,
(char *)&hashmark,

View File

@ -119,7 +119,7 @@ struct monitor_ops op50n_cmds = {
" ", /* end-of-command delimitor */
".\n", /* optional command terminator */
&op50n_ops, /* target operations */
"srec,binary", /* load types */
"srec,ascii-srec,default", /* load types */
op50n_regnames
};

View File

@ -114,7 +114,7 @@ struct monitor_ops w89k_cmds = {
"", /* end-of-command delimitor */
"", /* optional command terminator */
&w89k_ops, /* target operations */
"xmodem-srec,xmodem-som", /* load types */
"srec,xmodem-ascii,xmodem-srec,default",/* load types */
w89k_regnames /* registers names */
};